之前在學習 Kotlin 的時候,有整理了一篇關於 函數字面值 的博客。然後今天再回顧相關知識點的時候,感覺對這個概念加深了一點理解,而且之前那篇文章可能說得不太明白,於是這裏又整理下相關的想法,做一個補充,希望能夠幫助大家更加通俗的理解這個概念。
首先,函數字面值(量)即一段函數文本,說白了就是一段代碼,可以當作參數來傳遞。
比如下面的:
var tmp: ((Int) -> Boolean)? = null
定義了一個變量 tmp
,而該變量的類型就是 (Int) -> Boolean
這一函數類型(可爲空的),該類型的函數,需要傳遞一個 Int 類型的參數,返回 Boolean 類型的值。
這就跟下面的是類似
var tmp2: String? = null
定義一個變量 tmp2
,而該變量的類型就是 String 類型,即字符串類型。
當然, tmp
暫時只是定義了類型,然後如果給它賦值的話,可以是:
// 1-1
// num 即對應 Int 類型的參數,(num>10) 是一個表達式,對應着 Boolean 類型的返回值
tmp = { num -> (num > 10) }
此時,num -> (num > 10)
即是一個函數字面值,或者說,這個函數字面值即指的是 num -> (num > 10)
。
(題外話,如果函數只有一個參數的話,則該參數可以省略,默認以 it 關鍵字代替)
當然,tmp
的具體實現是不定的,可以是上面寫的那樣,也可以是:
// 2-1
tmp = { num -> (num >= 0) }
這裏就對應另外一種函數字面值了。
以上說到的兩種不同的函數字面值,他們唯一的共同點就是屬於 (Int) -> Boolean
類型。
接下來還有一點,既然是變量,就可以作爲方法參數傳遞,比如我定義一個方法:
fun method(a: ((Int) -> Boolean)?) {
val b = a?.invoke(3)
println(b)
}
該方法的參數 a
同樣也是 (Int) -> Boolean
這一函數類型,因此,在使用該 method()
方法時,就可以傳遞之前的兩種函數字面值,即 1-1
和 1-2
兩種不同的函數字面值。然後通過 invoke()
來觸發其執行,當然,需要傳遞一個 Int 類型的參數。
// 2-1
method({ num -> (num > 10) })
// 2-2
method({ num -> (num >= 0) })
對於 1-1 對應的函數字面量,其執行結果就爲 false,即會打印 fasle;
對於 1-2 對應的函數字面量,其執行結果就爲 true,即會打印 true;
類比到 Java 中,其實就類似於定義一個只有一個方法的接口,前面說的 “函數類型” 即對應該接口類型,而函數字面值,則對應着接口方法的具體實現。