欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于Kotlin中SAM轉(zhuǎn)換的那些事

 更新時間:2020年09月15日 09:54:56   作者:Dexlind  
這篇文章主要給大家介紹了關(guān)于Kotlin中SAM轉(zhuǎn)換的那些事,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

隨著 Kotlin 1.4 正式發(fā)布,關(guān)于 SAM 轉(zhuǎn)換的一些問題就可以蓋棺定論了。因為這里要講的都是些舊的東西,所以這是一篇灌水文。

Kotlin對SAM轉(zhuǎn)換的支持情況

在 1.4 發(fā)布之前,經(jīng)常有新人在群里提出關(guān)于 SAM 轉(zhuǎn)換的問題。

為了說明這個問題,要分成幾個情況來討論。

我們需要區(qū)分這個接口是Java接口還是Kotlin接口:

// 這是Java
interface JavaSome {
 void some(); 
}
// 這是Kotlin
interface KotlinSome {
 fun some()
}

以及區(qū)分在Java還是Kotlin里使用該接口:

// 這是Java, ISome是一個接口
void useSome(ISome some) {}
// 這是Kotlin, ISome是一個接口
fun useSome(some: ISome) {}

兩兩相乘,我們就需要對4種情況進行討論。當(dāng)然,useSome 函數(shù)都是在 Kotlin 里調(diào)用。

1、Java接口,Java使用

// Java
void useSome(JavaSome some) {}
// Kotlin
useSome {} // OK

這種情況下的 SAM 轉(zhuǎn)換,是自古以來 Kotlin 就支持的。

2、Java接口,Kotlin使用

// Kotlin
fun useSome(some: JavaSome) {}

useSome {} // 能否編譯成功跟Kotlin版本和編譯器參數(shù)有關(guān)

Kotlin 1.2 以及更舊版本不支持這種情況下的SAM轉(zhuǎn)換。

Kotlin 1.3 版本,Kotlin 官方團隊發(fā)現(xiàn)他們寫的那堆類型推斷算法是一座“屎山”,于是重新寫了套新的類型推斷算法,作為默認關(guān)閉的實驗性特性加入了 1.3 版本。新的類型推斷算法支持這種情況下的SAM轉(zhuǎn)換,不過需要手動傳入編譯器參數(shù)來開啟這個功能。

Kotlin 1.4 版本,由于新的類型推斷算法已經(jīng)默認開啟,所以這種情況下可以進行SAM轉(zhuǎn)換。

3、Kotlin接口,Kotlin使用

// Kotlin
fun useSome(some: KotlinSome) {}

useSome {} // 編譯錯誤!

這就是廣為人知、為人詬病的垃圾 Kotlin 不支持 SAM 轉(zhuǎn)換的情況。

在 Kotlin 1.4 版本,你需要在接口前加上關(guān)鍵字 fun,讓它成為一個 fun interface 才能享受到 SAM 轉(zhuǎn)換。

// Kotlin
fun interface KotlinSome {
 fun some()
}

fun useSome(some: KotlinSome) {}

useSome {} // OK

當(dāng)然 1.3 版本就別想了,老老實實升級吧。

4、Kotlin接口,Java使用

// Java
void useSome(KotlinSome some) {}
// Kotlin
useSome {} // 需要是 fun interface

非常少見。

和上面的第三種情況一樣,這需要 Kotlin 1.4 版本的 fun interface 才能進行 SAM 轉(zhuǎn)換。

5、帶有suspend函數(shù)的Kotlin接口

四天王有五個人不是常識么

fun interface Some {
 suspend fun some()
}

fun useSome(some: KotlinSome) {}

useSome {} // 嘻嘻

在 Kotlin 1.4 的測試版(里程碑版、RC版),可以編譯成功,但是運行起來會炸。原因在于 Kotlin 官方團隊并沒有寫好針對這種情況的代碼生成(codegen)。于是在 Kotlin 1.4 正式版,他們就 ban 掉了這樣的代碼,不允許 fun interface 擁有抽象 suspend 函數(shù)。

6、一些舊版本的bug

最經(jīng)典的是那個安卓的LiveData的某個函數(shù):

val liveData = MutableLiveData<Int>()
liveData.observe({ lifecycleOwner.lifecycle }, Observer { invokeMyMethod(it) })
// 第二個參數(shù)無法進行SAM轉(zhuǎn)換

詳見KT-14984。

新的類型推斷算法修正了這個bug。

SAM Constructor

在 1.3 以及更早的版本,針對上面所說的第二種情況,可以這樣使用:

// Kotlin
fun useSome(some: JavaSome) {}

useSome(JavaSome {})

想必各位過來人都知道這樣的寫法。

這里 JavaSome {},lambda 表達式前面的那個 JavaSome 就是所謂的 SAM 構(gòu)造器(SAM constructor),或者說是 SAM 適配器(SAM adapter)。

在現(xiàn)在 1.4 版本里,SAM constructor 已經(jīng)沒什么用了,主要用途是“憑空捏出”一個 SAM 接口的實例:

val ktSome = KotlinSome {} // 需要是 fun interface
val javaSome = JavaSome {}

// 錯誤用法
// val ktSome: KotlinSome = {}
// val javaSome: JavaSome = {}

SAM constructor 可以理解為編譯器為 SAM 接口生成了一個如下所示的輔助函數(shù),但是實際上這個函數(shù)并不存在。

// 這是Java
interface JavaSome {
 void some(); 
}
// 實際上并不存在的輔助函數(shù)
inline fun JavaSome(block: () -> Unit): JavaSome {
 return 編譯器的魔法
}

然后就有一些鮮為人知的用法,比如說這樣:

// Kotlin
val lambda: () -> Unit = { println("test") }
val kepa: JavaSome = JavaSome(lambda) // 嘻嘻
kepa.some() // 輸出 test

上面這段代碼確實是可以跑的。

甚至是這樣:

val lambda: () -> Unit = { println("test") }
val some: KFunction1<() -> Unit, JavaSome> = ::JavaSome // 嘻嘻
val kepa: JavaSome = some.invoke(lambda)
kepa.some()

這段代碼 IDEA 不會提示錯誤,但是會編譯失敗。

表面上看確實有這個輔助函數(shù),所以這樣的代碼可以通過 Kotlin 編譯器前端的檢查。但是實際上編譯器的后端并沒有辦法針對這樣的情況進行代碼生成,徹底懵逼了,boom!

你學(xué)到了什么

  • 一些無用的歷史知識
  • 關(guān)于 SAM constructor 的冷知識

本文完。

總結(jié)

到此這篇關(guān)于關(guān)于Kotlin中SAM轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)Kotlin中SAM轉(zhuǎn)換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決python字典對值(值為列表)賦值出現(xiàn)重復(fù)的問題

    解決python字典對值(值為列表)賦值出現(xiàn)重復(fù)的問題

    今天小編就為大家分享一篇解決python字典對值(值為列表)賦值出現(xiàn)重復(fù)的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • 用Python PIL實現(xiàn)幾個簡單的圖片特效

    用Python PIL實現(xiàn)幾個簡單的圖片特效

    這篇文章主要介紹了用Python PIL實現(xiàn)幾個簡單的圖片特效,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • Matplotlib的反轉(zhuǎn)軸、繪制雙軸和定制刻度詳解

    Matplotlib的反轉(zhuǎn)軸、繪制雙軸和定制刻度詳解

    這篇文章主要介紹了Matplotlib的反轉(zhuǎn)軸、繪制雙軸和定制刻度詳解,作為Python生態(tài)中應(yīng)用最廣泛的繪圖庫,Matplotlib用起來非常簡單,也很容易上手,本文匯總了和軸、刻度相關(guān)的七個Matplotlib使用技巧,并給出了實例代碼,需要的朋友可以參考下
    2023-08-08
  • python3.6 實現(xiàn)AES加密的示例(pyCryptodome)

    python3.6 實現(xiàn)AES加密的示例(pyCryptodome)

    本篇文章主要介紹了python3.6 實現(xiàn)AES加密的示例(pyCryptodome),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • python貪吃蛇核心功能實現(xiàn)上

    python貪吃蛇核心功能實現(xiàn)上

    我想大家都玩過諾基亞上面的貪吃蛇吧,這篇文章將帶你一步步用python語言實現(xiàn)一個snake小游戲,文中的示例代碼講解詳細,感興趣的可以了解一下
    2022-09-09
  • 用Python編程實現(xiàn)語音控制電腦

    用Python編程實現(xiàn)語音控制電腦

    是否經(jīng)常好萊塢電影里看強大的語音識別系統(tǒng)? 是否每每看到都會羨慕嫉妒恨? 可是我們真心買不起啊。
    2014-04-04
  • Python數(shù)據(jù)可視化plt.savefig如何將圖片存入固定路徑

    Python數(shù)據(jù)可視化plt.savefig如何將圖片存入固定路徑

    這篇文章主要介紹了Python數(shù)據(jù)可視化plt.savefig如何將圖片存入固定路徑問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • python實現(xiàn)猜單詞游戲

    python實現(xiàn)猜單詞游戲

    這篇文章主要為大家詳細介紹了python猜單詞小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • PyCharm使用技巧之設(shè)置背景圖片方式

    PyCharm使用技巧之設(shè)置背景圖片方式

    這篇文章主要介紹了PyCharm使用技巧之設(shè)置背景圖片方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • OpenCV圖像處理之圖像的二值化解讀

    OpenCV圖像處理之圖像的二值化解讀

    這篇文章主要介紹了OpenCV圖像處理之圖像的二值化解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02

最新評論