-
kotlin語法--->fun interface 函數式接口(使kotlin也符合SAM(single abstract method)轉換)
問題出處Compose中的layout函數,在進行自定義layout時,它的第三個參數也可以使用尾隨的lambda語法來寫,當時感覺比較疑惑.因為kotlin在調用java中的函數式接口是可以使用lambda語法來簡寫的。
但是kotlin調用自身的”函數式接口“時會出現編譯時錯誤。下面是一個例子.
fun setMyListener(listener: MyListener) { listener.onCheckdChange("name","zyt") } interface MyListener { fun onCheckedChanged(param1: String, param2: String) } fun mian(){ // 當我們通過SAM轉譯調用時,會出現錯誤 setMyListener { a, b -> print("param1:$a,param2:$b") // Compile time error } }
在我們調用java中的函數式接口時,kotlin是可以使用lambda來進行簡寫的。如下
// Test.java public interface Test { void onChanged(); } //.kt fun main(){ setTest{ // 這里並不會出現問題 println("onChanged") } } fun setTest(test: Test) { test.onChanged() }
可以理解為kotlin兼容java的SAM轉換.但是也有解決辦法,如下。
解決方法1:類似於java中的匿名內部類
setMyListener(object : MyListener{ override fun onCheckdChange(param1: String, param2: String) { TODO("Not yet implemented") } })
解決方法2:先看一下我當時遇到的疑惑,如下圖1。因為根據我前面的知識來理解,是不可使用尾隨lambda來進行簡寫的,我覺得編輯器應該報錯啊。
圖1但是圖2並沒有報錯。
圖2我接着點進MeasurePolicy進入看,一開始沒有注意到interface前有一個fun修飾符,
// MeasurePolicy.kt @Stable fun interface MeasurePolicy { // 就這一個抽象方法(沒有函數體) fun MeasureScope.measure( measurables: List<Measurable>, constraints: Constraints ): MeasureResult 。。。。。。 }
接下來我試了一下,如下
fun setMyListener(listener: MyListener) { listener.onCheckdChange("name","zyt") } fun interface MyListener { // fun interface 我的理解就是函數式接口,這里必須包含一個抽象方法(也就是沒有函數體),沒有抽象方法編譯不通過 fun onCheckdChange(param1: String, param2: String) } // 那么接下來就可以使用lambda來進行調用了(kotlin自身也符合SAM轉換了) setMyListener { a, b -> println("param1:$a,param2:$b") }