Для чего нужен expect actual?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Назначение expect/actual в Kotlin Multiplatform
В контексте Kotlin Multiplatform (KMP), механизм expect/actual — это ключевая система декларации платформо-специфичной реализации, которая обеспечивает общий API для кода, который должен работать на разных платформах (Android, iOS, JVM, JavaScript и т.д.), но требует разных реализаций под капотом.
Основная цель
Главная цель — разделение объявления общего контракта (интерфейса) от его платформо-зависимой реализации. Это позволяет писать общий код (общую бизнес-логику) в commonMain, объявляя ожидаемые функции, классы или свойства, а затем предоставлять конкретные реализации для каждой целевой плаформы в соответствующих исходных наборах (androidMain, iosMain, jsMain и др.).
Как это работает
- Объявление
expectв общем исходном наборе (commonMain) определяет контракт. - Реализация
actualв платформенных исходных наборах предоставляет конкретную реализацию для каждой платформы.
Пример для работы с текущим временем на разных платформах:
// В commonMain/TimeUtils.kt
expect fun currentTimeMillis(): Long
// В androidMain/TimeUtils.kt
import android.os.SystemClock
actual fun currentTimeMillis(): Long {
return SystemClock.elapsedRealtime()
}
// В iosMain/TimeUtils.kt
import platform.Foundation.NSDate
actual fun currentTimeMillis(): Long {
return (NSDate().timeIntervalSince1970() * 1000).toLong()
}
Ключевые преимущества использования expect/actual
- Единый API в общем коде: Разработчик в общем модуле видит только
expect-объявления, что упрощает работу и скрывает сложности платформ. - Безопасность типов: Компилятор проверяет соответствие
actual-реализацийexpect-объявлениям (совпадение имён, типов параметров, возвращаемых типов). - Упрощённая навигация: IDE (IntelliJ IDEA/Android Studio) предоставляют удобную навигацию между
expectиactual-объявлениями. - Автоматическое разрешение при компиляции: Компилятор Kotlin сам выбирает нужную
actual-реализацию в зависимости от целевой платформы.
Области применения
- Доступ к платформенным API: Работа с файловой системой, сетью, нативными UI-компонентами.
- Использование платформенных библиотек: Например,
okHttpна Android иNSURLSessionна iOS для сетевых запросов. - Различия в поведении: Когда логика должна немного отличаться на разных платформах из-за особенностей ОС или аппаратного обеспечения.
Важные ограничения и правила
- Соответствие модификаторов видимости:
actual-реализация не может быть менее доступной, чемexpect-объявление. - Обязательность реализации: Для каждой
expect-декларации должна быть ровно однаactual-реализация на каждую целевую платформу (в соответствующем исходном наборе). - Использование в общем коде:
expect-функции/классы можно свободно использовать в общем коде, как если бы они были реализованы прямо там.
Отличие от интерфейсов и абстрактных классов
В отличие от обычных абстрактных деклараций, expect/actual разрешаются на этапе компиляции, а не выполнения. Это не полиморфизм в runtime, а механизм метапрограммирования, где компилятор генерирует соответствующий нативный код для каждой платформы.
Таким образом, expect/actual — это фундаментальный механизм Kotlin Multiplatform, который делает возможным кроссплатформенную разработку с сохранением доступа ко всем нативным возможностям каждой платформы, обеспечивая при этом чистую архитектуру и безопасность типов.