Интернационализация (i18n) в Kotlin: Полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Интернационализация (i18n) в Kotlin: Полное руководство с примерами

Интернационализация (i18n) — это процесс проектирования и разработки программного обеспечения, позволяющий адаптировать его для различных языков и регионов без внесения изменений в исходный код. В экосистеме Kotlin, будь то Android-приложения, серверные проекты на Ktor или мультиплатформенные решения с Kotlin Multiplatform, правильная реализация i18n является критически важной для глобального успеха продукта. В этой статье мы рассмотрим основные подходы, инструменты и лучшие практики для интернационализации Kotlin-приложений.

Почему i18n важен в Kotlin?

Kotlin, будучи современным языком, полностью совместимым с Java, наследует все возможности Java для локализации, но также предлагает свои уникальные решения. Правильная интернационализация позволяет:

  • Значительно расширить аудиторию вашего приложения
  • Улучшить пользовательский опыт для носителей разных языков
  • Соблюдать законодательные требования различных стран (например, касающиеся валют или форматов дат)
  • Упростить процесс добавления новых языков в будущем

Основные подходы к i18n в Kotlin

1. Использование Resource Bundle (Java-совместимый подход)

Самый распространенный и простой способ — использование стандартных ResourceBundle и файлов свойств (.properties). Этот метод идеально подходит для консольных приложений и серверных проектов на Kotlin.

// messages_en.properties
greeting=Hello, {0}!
farewell=Goodbye

// messages_ru.properties
greeting=Привет, {0}!
farewell=До свидания
import java.util.ResourceBundle
import java.text.MessageFormat

fun main() {
    val bundle = ResourceBundle.getBundle("messages", Locale("ru"))
    val greeting = MessageFormat.format(bundle.getString("greeting"), "Мир")
    println(greeting) // Выведет: Привет, Мир!
    
    println(bundle.getString("farewell")) // Выведет: До свидания
}

2. Kotlin-специфичный подход с функциями-расширениями

Kotlin позволяет создавать более лаконичный и безопасный API для работы с локализацией, используя функции-расширения и делегированные свойства.

import java.util.*
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty

class I18n(private val baseName: String) {
    private val bundle: ResourceBundle
        get() = ResourceBundle.getBundle(baseName)
    
    operator fun provideDelegate(
        thisRef: Any?, 
        prop: KProperty<*>
    ): ReadOnlyProperty {
        return ReadOnlyProperty { _, _ -> bundle.getString(prop.name) }
    }
}

object Strings {
    val i18n = I18n("messages")
    
    val greeting by i18n
    val farewell by i18n
}

fun main() {
    // Автоматически использует локаль системы
    println(Strings.greeting) // Выведет соответствующее значение из файла свойств
    println(Strings.farewell)
}

Инструменты для локализации в Kotlin

1. Kotlin Multiplatform (KMP) и expect/actual

Для мультиплатформенных проектов Kotlin предлагает мощный механизм expect/actual, позволяющий объявлять общий API для i18n и реализовывать его отдельно для каждой платформы.

// В общем коде (commonMain)
expect class PlatformStringResources {
    fun getString(key: String, vararg args: Any?): String
}

// В Android (androidMain)
actual class PlatformStringResources {
    private val context: Context = // получаем контекст
    
    actual fun getString(key: String, vararg args: Any?): String {
        val resId = context.resources.getIdentifier(key, "string", context.packageName)
        return context.getString(resId, *args)
    }
}

// В iOS (iosMain)
actual class PlatformStringResources {
    actual fun getString(key: String, vararg args: Any?): String {
        return NSString.localizedStringWithFormat(
            NSLocalizedString(key, comment: ""),
            *args
        )
    }
}

2. Библиотека kotlin-i18n

Существует специализированная библиотека kotlin-i18n, которая предоставляет более продвинутые возможности, включая поддержку плюрализации и контекстных форм.

// build.gradle.kts
implementation("com.github.osipxd:kotlin-i18n:1.2.0")

// Пример использования
import com.github.osipxd.i18n.*

fun main() {
    val resources = I18nResources.load("messages")
    
    // Плюрализация
    println(resources.plural("apples.count", 1)) // 1 яблоко
    println(resources.plural("apples.count", 2)) // 2 яблока
    println(resources.plural("apples.count", 5)) // 5 яблок
}
                
    
    

Рекомендаций