iT邦幫忙

2022 iThome 鐵人賽

DAY 11
0
Mobile Development

Kotlin 全面啟動 系列 第 11

[Kotlin 全面啟動] Expect & Actual

  • 分享至 

  • xImage
  •  

眼尖的讀者不知道有沒有發現,我們的 Hello World 專案執行起來 Android 跟 iOS 的顯示其實是不一樣的,iOS 是顯示 “Hello, iOS 15.5!“,而 Android 是顯示 “Hello, Android 33!”。

這個技術在當我們想要在不同平台使用不同的 library 非常實用,但如果無法理解就不能再需要的時候使用了,讓我們回頭看看 source code 了解 KMM 是怎麼做到的吧!

在 shared/src 這個資料夾下,大家會發現以下的結構:

jintinlin@Jintins-Air src % tree     
.
├── androidMain
│   ├── AndroidManifest.xml
│   └── kotlin
│       └── com.jintin.xxx
│                       └── Platform.kt
├── commonMain
│   └── kotlin
│       └── com.jintin.xxx
│                       └── Platform.kt
└── iosMain
    └── kotlin
        └── com.jintin.xxx
                        └── Platform.kt

在 commonMain、androidMain、iosMain 原來各有一個 Platform.kt,看來玄機就在這邊了,讓我們打開各別檔案看一下:

// commonMain
expect class Platform() {
    val platform: String
}

// androidMain
actual class Platform actual constructor() {
    actual val platform: String = "Android ${android.os.Build.VERSION.SDK_INT}"
}

// iosMain
actual class Platform actual constructor() {
    actual val platform: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
}

這邊就會看到我們的主題 expect 跟 actual 了,expect 只提供協定,需要具體的 actual 來實作功能的細節,而二者必須透過一樣的名稱讓 compiler 建立連結綁定,所以如果沒有對應的 expect 或 actual 或是有多個相同物件都會造成 compile error,擷取官網的關係圖如下所示:

https://ithelp.ithome.com.tw/upload/images/20220925/20120419hSRJLUjy0x.png

這邊也建議大家可以回頭在 androidMain 或 iosMain 改一下 code,看重新 run 起來會不會真的改變。

看到這邊是不是讓大家想到 interface 的設計呢?但 expect/actual 跟 interface 是有點不一樣的,如果是使用 interface 則上層的 interface 跟下層的實作是二個不同的物件,你必須要有具體實作的 reference 才能夠使用實作的功能,而 expect / actual 就如剛剛所說可以視為同個物件操作,所以當我們想把不同平台的實現分開的時候就會非常的適合。

Expect/Actual 使用上還有蠻多小細節,比如說,expect class 裡的所有 property/function 都必須為 expect,actual 裡可以有其他定義以外的 property/function,除了 class 之外,function、interface、property、top level function 也都可以使用 expect 來定義,具體使用起來真的是蠻方便的。

最後,我想說的是 KMM 作為 Kotlin 官方所推出的一套工具,跟一般的第三方工具是完全不一樣的,有點像 JxJava 跟 coroutine 的比較一樣,expect/actual 非常粗暴的直接從語法層面來支援這個功能,以我們作為 KMM 的使用者來說真是一大福音!


上一篇
[Kotlin 全面啟動] Add dependency
下一篇
[Kotlin 全面啟動] Coroutine
系列文
Kotlin 全面啟動 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言