Почему вашему приложению нужна интернационализация прямо сейчас
\n\nПредставьте: вы написали крутое Kotlin-приложение — удобное, быстрое, с красивым UI. Но все подписи на русском. Пользователь из Берлина или Токио открывает ваш продукт... и закрывает через 10 секунд. Почему? Потому что он не понимает ни слова. Интернационализация (i18n) — это не просто «кнопка перевода», это мост между вашим кодом и миллионами пользователей по всему миру.
\n\nВ этой статье мы детально разберем, как правильно внедрить интернационализацию Kotlin в проектах любого масштаба: от Android-приложений до серверных сервисов на Ktor. Вы узнаете, как избежать типичных ошибок, как использовать Kotlin Multiplatform для общей логики и почему «магические строки» — это зло.
\n\nОсновы i18n в Kotlin: от простого к сложному
\n\nФайлы ресурсов: фундамент локализации
\n\nСамый надежный способ организовать локализацию Kotlin-приложения — вынести все строковые литералы в отдельные файлы ресурсов. В Android Studio это стандартный strings.xml, но для чистого Kotlin (бэкенд, десктоп) можно использовать .properties или JSON.
Пример для Android:
\n\n// res/values/strings.xml (русский — по умолчанию)\n<resources>\n <string name="app_name">Моё приложение</string>\n <string name="welcome_message">Добро пожаловать, %s!</string>\n <string name="points">У вас %d баллов</string>\n</resources>\n\n// res/values-en/strings.xml (английский)\n<resources>\n <string name="app_name">My App</string>\n <string name="welcome_message">Welcome, %s!</string>\n <string name="points">You have %d points</string>\n</resources>\n\nВ коде обращаемся через context.getString():
val userName = "Алексей"\nval message = context.getString(R.string.welcome_message, userName)\n// Результат: "Добро пожаловать, Алексей!" (или "Welcome, Alexey!" для английского)\n\nОбратите внимание: мы используем %s для строк и %d для чисел. Никогда не склеивайте строки вручную — в японском или арабском порядок слов может быть другим.
Работа с множественными числами
\n\nРусский язык славится сложными правилами склонения: 1 балл, 2 балла, 5 баллов. В английском проще: 1 point, 2 points. Интернационализация Kotlin должна это учитывать.
\n\nВ Android для этого есть <plurals>:
// strings.xml\n<plurals name="points_count">\n <item quantity="one">%d балл</item>\n <item quantity="few">%d балла</item>\n <item quantity="many">%d баллов</item>\n</plurals>\n\n// В коде\nval points = 3\nval text = resources.getQuantityString(R.plurals.points_count, points, points)\n// "3 балла"\n\nДля серверного Kotlin можно использовать библиотеку icu4j или написать простой парсер самостоятельно. Главное правило: никогда не хардкодить текст с числами.
Интернационализация в Kotlin Multiplatform (KMP)
\n\nЕсли вы пишете кроссплатформенное приложение на Kotlin Multiplatform, задача усложняется. Общий код не имеет доступа к Android-ресурсам. Решение — использовать общий интерфейс и платформенные реализации.
\n\nАрхитектура для KMP
\n\nСоздайте expect-класс в общем модуле:
\n\n// commonMain\nexpect class StringProvider {\n fun getString(key: String, vararg args: Any): String\n}\n\n// Использование в общем коде\nclass Greeting(private val strings: StringProvider) {\n fun greet(name: String): String {\n return strings.getString("welcome", name)\n }\n}\n\nРеализация для Android: