← Назад к вопросам

Для чего нужен expect actual?

2.2 Middle🔥 111 комментариев
#Kotlin основы#Многомодульность

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Назначение expect/actual в Kotlin Multiplatform

В контексте Kotlin Multiplatform (KMP), механизм expect/actual — это ключевая система декларации платформо-специфичной реализации, которая обеспечивает общий API для кода, который должен работать на разных платформах (Android, iOS, JVM, JavaScript и т.д.), но требует разных реализаций под капотом.

Основная цель

Главная цель — разделение объявления общего контракта (интерфейса) от его платформо-зависимой реализации. Это позволяет писать общий код (общую бизнес-логику) в commonMain, объявляя ожидаемые функции, классы или свойства, а затем предоставлять конкретные реализации для каждой целевой плаформы в соответствующих исходных наборах (androidMain, iosMain, jsMain и др.).

Как это работает

  1. Объявление expect в общем исходном наборе (commonMain) определяет контракт.
  2. Реализация 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, который делает возможным кроссплатформенную разработку с сохранением доступа ко всем нативным возможностям каждой платформы, обеспечивая при этом чистую архитектуру и безопасность типов.