一、函式型別
在之前我們用到的lambda的語法中val sum: (Int, Int) -> Int = {x: Int, y: Int -> x + y},(Int, Int) -> Int 為函式型別,引數和回傳值用 -> 分割開,引數的個數可以是0個或者多個,回傳值為空時不可以省略,表示方法可以分為三類,
1.由一個()括起來的引數串列和用->分割的回傳型別
() -> Unit //無參,無回傳值的函式型別
(T) -> Unit //接收T型別,無回傳值的函式型別
(T) -> R //接收T型別、并且回傳R型別值的函式型別
(T, R) -> Unit //接收T和R型別引數無回傳值的函式型別
(T, R) -> R//接收T和R型別引數,并且回傳R型別值的函式型別
2.帶有接受者的函式型別,比如 A.(B) -> C 表示在接收者物件A上用引數B呼叫并回傳值C的函式,可以直接使用接受者物件的成員(屬性和方法),也可以使用this訪問其成員,和擴展函式很類似,(kotlin鼓勵使用擴展函式,每當你有一個主要用于某個物件的函式時,可以考慮使其成為一個以該物件為接收者的擴展函式,為了盡量減少 API 污染,盡可能地限制擴展函式的可見性,根據需要,使用區域擴展函式、成員擴展函式或者具有私有可視性的頂層擴展函式,)
帶與不帶接受者的函式型別可以互換,接收者可以最為第一個引數,反之亦然,例如 (A, B)->C 型別的值可以賦值給接收A.(B)->C型別地方,反之亦然,
fun Person.getNextYearAge2(): Int {
return age + 1
}
fun getAge(block: (Person) -> Int): Int {
return block(Person(12, "A"))
}
fun main(args: Array<String>) {
val age = getAge(Person::getNextYearAge2)
}
3.掛起函式屬于特殊種類的函式型別,它的表示法中有一個 suspend 修飾符 ,例如 suspend () -> Unit或者 suspend A.(B) -> C,
Tips:(1)函式型別可空時使用()? ((Int, Int) -> Int)?
(2)函式型別是又結合的 (Int)-> ((Int) -> Unit) 等價于 (Int) -> (Int) -> Unit
二、 型別別名 使用關鍵詞 typealias
typealias lambdaAlias = (Int) -> Boolean
當某個函式型別被多次參考時可以使用函式別名,宣告函式型別別名不會產生新的變數
三、函式型別實體化
實體化的函式型別可以作為引數傳遞到函式中,函式實體化的方式常用的有三種,
(1)使用函式字面值的代碼塊,lambda運算式或者匿名函式
lambda運算式 :{a, b -> a+b}
fun getInt(block: (String) -> Int) {
//...
}
getInt { it.toIntOrNull() ?: 0 }
匿名函式:fun (s: String): Int { return s.}
fun getInt(block: (String) -> Int) {
//...
}
getInt(fun(s: String): Int { return s.toIntOrNull() ?: 0 })
匿名函式可以指定回傳型別(大部分情況下lambda回傳型別可以自動推到),匿名函式不能寫到()外邊,一個不帶標簽的return會在fun關鍵詞宣告的函式中回傳,因此lambda運算式會在包含他的函式中回傳(只有行內函式中才能使用不帶標簽的retuen),匿名函式中return將會在自身回傳,
(2)使用已有宣告的可呼叫參考
- 頂層、區域、成員、擴展函式:
::isOdd、String::toInt, - 頂層、成員、擴展屬性:
List<Int>::size, - 建構式:
::Regex
fun Person.getNextYearAge2(): Int {
return age + 1
}
fun getNextYearAge(person: Person): Int {
return person.age + 1
}
fun getAge(block: (Person) -> Int): Int {
return block(Person(12, "A"))
}
fun main(args: Array<String>) {
print("A next year age = ${getAge(::getNextYearAge)}")
val age = getAge(Person::getNextYearAge2)
}
(3)使用實作函式型別介面的自定義類的實體
class IntTransformer: (Person) -> Int {
override fun invoke(p1: Person): Int {
TODO("Not yet implemented")
}
}
fun getAge(block: (Person) -> Int): Int {
return block(Person(12, "A"))
}
fun main(args: Array<String>) {
print("A next year age = ${getAge(IntTransformer())}")
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/293205.html
標籤:其他
下一篇:react-native錯誤Make sure you have the Android development environment set up處理
