expect/actual-Mechanismus für Plattform-APIs
Deklarieren Sie erwartete Deklarationen im gemeinsamen Code und stellen Sie pro Plattform tatsächliche Implementierungen bereit.
expect/actual-Mechanismus für Plattform-APIs ist eine kostenlose Kotlin Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Kotlin Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.
Das expect/actual-Muster
expect deklariert einen API-Vertrag in commonMain. Jede Plattform stellt eine actual-Implementierung bereit. Der Compiler erzwingt, dass alle Targets eine actual-Implementierung besitzen.
// commonMain:
expect fun platformName(): String
// androidMain:
actual fun platformName(): String = "Android ${android.os.Build.VERSION.SDK_INT}"
// iosMain:
actual fun platformName(): String = UIDevice.currentDevice.systemName()expect class
expect class deklariert eine Klasse mit ihrer API in commonMain. Jede Plattform stellt die vollständige Implementierung bereit.
// commonMain:
expect class DateTime {
fun format(pattern: String): String
val timestamp: Long
}
// androidMain:
actual class DateTime {
actual val timestamp = System.currentTimeMillis()
actual fun format(pattern: String): String =
java.text.SimpleDateFormat(pattern).format(java.util.Date(timestamp))
}expect object
expect object deklariert ein Singleton mit seinem Vertrag. Das ist nützlich für plattformspezifische Hilfsfunktionen wie Logging, Einstellungen oder Analytics.
// commonMain:
expect object Logger {
fun debug(msg: String)
fun error(msg: String, cause: Throwable? = null)
}
// androidMain:
actual object Logger {
actual fun debug(msg: String) = android.util.Log.d("App", msg)
actual fun error(msg: String, cause: Throwable?) =
android.util.Log.e("App", msg, cause)
}expect val / fun auf oberster Ebene
Top-Level-expect val und expect fun sind unkompliziert und eignen sich gut für zustandslose plattformspezifische Hilfsfunktionen.
// commonMain:
expect val isDebugBuild: Boolean
expect fun generateUUID(): String
// androidMain:
actual val isDebugBuild: Boolean = BuildConfig.DEBUG
actual fun generateUUID(): String = java.util.UUID.randomUUID().toString()
// iosMain:
actual val isDebugBuild: Boolean = false // or a native flag
actual fun generateUUID(): String = NSUUID().UUIDString()expect fun mit Standardimplementierung
Seit Kotlin 1.9+ kann expect fun über expect fun f() { } eine Standardimplementierung besitzen. Plattformen können diese überschreiben oder die Standardimplementierung verwenden.
// commonMain (Kotlin 1.9+):
expect fun log(msg: String) {
println("[DEFAULT] $msg") // used if no actual overrides
}
// androidMain:
actual fun log(msg: String) = android.util.Log.d("KMP", msg)
// iosMain (uses default):
// no actual needed — default is usedActual Typealias
Wenn die Plattform bereits genau die benötigte Klasse besitzt, verwenden Sie actual typealias, um auf sie zu verweisen, statt sie zu wrappen.
// commonMain:
expect class AtomicInt {
fun get(): Int
fun incrementAndGet(): Int
}
// androidMain / jvmMain:
actual typealias AtomicInt = java.util.concurrent.atomic.AtomicInteger
// iosMain:
actual class AtomicInt {
private var value = 0
actual fun get() = value
actual fun incrementAndGet() = ++value
}expect interface (indirektes Muster)
Für mehr Flexibilität deklarieren Sie ein Interface in commonMain und verwenden expect/actual nur für die Factory, die die plattformspezifische Instanz erstellt.
// commonMain:
interface FileStorage {
suspend fun readFile(path: String): ByteArray
suspend fun writeFile(path: String, data: ByteArray)
}
expect fun createFileStorage(): FileStorage
// androidMain:
actual fun createFileStorage(): FileStorage = AndroidFileStorage()
// iosMain:
actual fun createFileStorage(): FileStorage = IosFileStorage()Testen mit expect/actual
Testen Sie in commonTest die gemeinsame API. Die actual-Implementierungen werden während der plattformspezifischen Test-Tasks ausgeführt (testDebugUnitTest auf Android, iosX64Test auf iOS).
// commonTest:
import kotlin.test.Test
import kotlin.test.assertNotNull
class PlatformTest {
@Test
fun testUUID() {
val uuid = generateUUID()
assertNotNull(uuid)
println("UUID: $uuid")
}
}Häufige Fehler
Jedes deklarierte expect muss in ALLEN konfigurierten Targets ein actual besitzen, andernfalls schlägt der Build fehl. Fehlende actual-Implementierungen werden zur Compile-Zeit erkannt.
// If you add a new target (e.g., jvmMain), you must add:
// actual fun platformName(): String = "JVM"
// Otherwise:
// error: Expected function platformName has no actual declaration in module :shared for JVM
fun main() { println("Missing actuals = compile error") }Expect-Annotationsklasse
expect annotation class ermöglicht die Zuordnung plattformspezifischer Annotationen – zum Beispiel die Zuordnung einer gemeinsamen, @Parcelize ähnlichen Annotation zum Android-Parcelize-Plugin.
// commonMain:
expect annotation class CommonParcelize()
// androidMain:
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.BINARY)
actual annotation class CommonParcelize
// iosMain:
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.BINARY)
actual annotation class CommonParcelizePraxisbeispiel: Keychain/Preferences
Ein typisches expect/actual-Praxisbeispiel ist ein Interface für sichere Speicherung, bei dem Android EncryptedSharedPreferences und iOS den Keychain verwendet.
// commonMain:
expect class SecureStorage {
fun save(key: String, value: String)
fun get(key: String): String?
}
// androidMain:
actual class SecureStorage {
private val prefs = /* EncryptedSharedPreferences */ mapOf<String,String>()
actual fun save(key: String, value: String) { /* ... */ }
actual fun get(key: String): String? = null // simplified
}Kurzer Check
Was geschieht zur Compile-Zeit, wenn eine expect-Deklaration für ein Target kein actual besitzt?
Zusammenfassung
expect deklariert die API in commonMain. actual stellt die plattformspezifische Implementierung bereit. Verwenden Sie actual typealias, wenn der benötigte Typ auf der Plattform bereits vorhanden ist. Fehlende actual-Implementierungen werden zur Compile-Zeit erkannt – es gibt keine Überraschungen zur Laufzeit.
Lerne Kotlin mit einem KI-Tutor — kostenlos
Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.
- Kurse
- 51
- Lektionen
- 203
Häufig gestellte Fragen
Ist die Lektion „expect/actual-Mechanismus für Plattform-APIs“ kostenlos?
Ja — der vollständige Text von „expect/actual-Mechanismus für Plattform-APIs“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Kotlin Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „expect/actual-Mechanismus für Plattform-APIs“?
Deklarieren Sie erwartete Deklarationen im gemeinsamen Code und stellen Sie pro Plattform tatsächliche Implementierungen bereit. Du übst Kotlin Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Kotlin Academy zu starten?
Keine Vorkenntnisse erforderlich. Kotlin Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „expect/actual-Mechanismus für Plattform-APIs“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Kotlin Academy-Lektion Code schreiben und ausführen?
Ja. Jede Kotlin Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- KMP-Projektstruktur: commonMain, androidMain, iosMain
- expect/actual-Mechanismus für Plattform-APIs
- Repository- und Use-Case-Schichten gemeinsam nutzen
- Dependency Injection in KMP mit Koin