foreword
Kotlin's expect keyword is generally used on multiple platforms, such as declaring a method signature in common in a multi-platform project, and then implementing the method by different platforms, thereby implementing a multi-platform (cross-platform) method.
To create a KMM project, you can refer to: KMM (2) + Compose (2) to develop a Kotlin multi-platform application
text
Next, let’s talk about several declaration methods of Kotlin expect
1. Top-level functions and top-level extension functions
Declare in the commonMain folder:
Implemented in the androidMain (and other platforms) folder:
After declaration and implementation, the corresponding method can be used in both shared code and platform code
2. Properties
statement:
expect val isDebug: Boolean
accomplish:
actual val isDebug: Boolean = BuildConfig.DEBUG
3. Notes
statement:
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
internal expect annotation class ExpectAnnotation()
accomplish:
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
internal actual annotation class ExpectAnnotation()
4. Enumeration
statement:
expect enum class Enum
accomplish:
actual enum class Enum {
enum1,
enum2,
enum3,
}
5. Interface
statement:
expect interface Interface {
fun fun1()
fun fun2(): String
}
accomplish:
actual interface Interface {
actual fun fun1()
actual fun fun2(): String
fun fun3() {
"fun3".loge()
}
}
6. class
statement:
expect class Class() {
fun fun1()
fun fun2(): String
}
accomplish:
actual class Class {
actual fun fun1() {
}
actual fun fun2(): String {
return getUUID()
}
}
After testing, the sealed class can be used, but the data class does not seem to be used
ps: Using interfaces and classes in public modules temporarily requires manual package import
7.typealias
Using kotlin's typealias feature, we can map an implemented class to an implementation of expect
Let's implement a multi-platform ViewModel next
First go to the build.gradle.kts file in the common directory
Add viewmodel dependencies:
val androidMain by getting {
dependencies {
api("androidx.appcompat:appcompat:1.2.0")
api("androidx.core:core-ktx:1.3.1")
api("androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1")//增加vm依赖
}
}
statement:
expect open class MViewModel() {
protected open fun onCleared()
}
androidMain implementation (use ViewModel directly):
import androidx.lifecycle.ViewModel
open class MyViewModel : ViewModel() {
override fun onCleared() {
super.onCleared()
}
}
actual typealias MViewModel = MyViewModel
ps: Let me talk about why you need to implement ViewModel before using typealias. First of all, ViewModel is an abstract class, but there is no need to make it abstract. The most important thing is that Kotlin's protected and Java's protected have different visibility, so typealias cannot be directly matched. Above, I don’t know how Kotlin will make up for this pit in the future, refer to the following picture and article:
Learning Kotlin (3) classes and interfaces - Programmer Sought
desktopMain implementation:
actual open class MViewModel {
protected actual open fun onCleared() {
}
}
The above code is placed in the expectations directory of Github: ltttttttttttt/KMM_and_Compose_Sample
Refer to Kotlin official website: Connect to platform-specific APIs | Kotlin
If there are mistakes, welcome to point out
end