hi各位,這章主要是lambda表達式的快速入門。
大家都知道程式設計有OOP與FP(函數式程式設計),Kotlin支援将函數,像java中的對象那樣來使用的,是以就有了lambda表達式。
一:閉包: "()->Int return{}"
一個函數傳回了一個内部函數,該内部函數引用了外部函數的相關參數和變量,我們把該傳回的内部函數稱為閉包。-網上找的定義,覺得挺合适。
// 一個函數傳回了一個内部函數,該内部函數引用了外部函數的相關參數和變量,我們把該傳回的内部函數稱為閉包。
fun fun1(): () -> Int {
var out = 1
return {
out + 5//引用外了外部函數中的out參數變量。把這個叫為閉包
}
}
經驗:
閉包是Kotlin的核心文法,隻有完全掌握Kotlin的閉包功能,才能寫出優秀的Kotlin代碼。
二:函數引用: "::"
是在高階函數中使用,高階函數是說在你的fun()的參數中有()->Int這種的函數引用,有這種參數的函數就叫做高階函數。https://blog.csdn.net/pangzaifei/article/details/85076557
//testFun: (Int, Int) -> Int就是函數類型,是以test2就是高階函數
fun test2(n1: Int, n2: Int, testFun: (Int, Int) -> Int): Int {
return testFun(n1, n2)
}
fun test3Add(num1: Int, num2: Int): Int {
return num1 + num2
}
fun test3Multiply(num1: Int, num2: Int): Int {
return num1 * num2
}
//test2()第三個參數是函數類型,是以test2就是高階函數。第三個參數可以接受函數類型的範圍是(Int,Int)->Int的,也就是test3Add()和test3Multiply()這兩個函數
//下面fun2()是調用test2()方法,第三個參數選擇傳入test3Add()或者test3Multiply()這兩個函數來相加或者相乘的操作,使用::來擷取函數引用
fun fun2() {
//擷取相加結果
val addResult = test2(10, 5, this::test3Add)
Log.e("fffpzf", "函數引用(::)擷取到相加結果:$addResult")
//擷取相城結果
val multiplayResult = test2(10, 5, this::test3Multiply)
Log.e("fffpzf", "函數引用(::)擷取到相乘結果:$multiplayResult")
}
===
E/fffpzf: 函數引用(::)擷取到相加結果:15
E/fffpzf: 函數引用(::)擷取到相乘結果:50
===
經驗:
函數引用也是Kotlin的核心文法,在開發中會經常使用到。
函數引用補充:
在Android開發中經常使用到startActivity(inetn())啟動一個頁面,那麼調轉的Activity就需要用::引用來實作。如下
//MainActivity::class.java目前頁面跳轉到MainActivity頁面
startActivity(Intent(this, MainActivity::class.java))
三:lambda表達式 "{}"
在高階函數的基礎上,Kotlin可以自動推斷出參數類型,傳回值不需要寫,自動判斷出傳回類型,是以就有了{},下面是變形步驟。轉載請注明出處:https://blog.csdn.net/pangzaifei/article/details/85076557
fun fun3() {
//看test2的第三個參數
val test2 = test2(10, 5, { m, n -> m + n })
Log.e("fffpzf", "lambda表達式初步變形1結果:$test2")
}
fun fun4() {
//看test2的第三個參數
//如果最後一個參數是lambda表達式,那麼()可以前提,類似下面這種
val test2 = test2(10, 5) { m, n -> m + n }
Log.e("fffpzf", "lambda表達式有參變形2結果:$test2")
}
===
E/fffpzf: lambda表達式初步變形1結果:15
lambda表達式有參變形2結果:15
===
fun fun5() {
val setOf = mutableSetOf<String>()
setOf.add("set_a")
setOf.add("set_b")
setOf.add("set_c")
//如果lamdba是無參數的,就可以删除(),那麼就變成forEach{}這樣的了
setOf.forEach {
if (it == "set_a") Log.e("fffpzf", "擷取到:set_a") else Log.e("fffpzf", "我是:$it")
}
//下面這是forEach的源碼,我們發現裡面隻有一個action: (T) -> Unit函數參數,是以這就是我們為什麼在用forEach{}周遊的時候可以直接用{}
//同時,如果隻有一個參數,那麼可以省略參數名,然後用it來替代它。這也就是為什麼forEach{}中可以用it
@kotlin.internal.HidesMembers
public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit {
for (element in this) action(element)
}
}
經驗:
lambada表達式是Kotlin的核心文法,lambda表達式可以是無參數的,也可以是有參數的。如果是無參數的lambda表達式,按照Kotlin的規則,最後一個參數是無參的閉包,那麼可以删除最後一個()。是以為什麼我們會看到.forEach{}這種樣式,lambda表達式常常同閉包一起聯合使用。
四:lambda表達式的傳回值:{這裡面的最後一行就是傳回值}
五:一些lambda表達式例子
fun fun6() {
val setOf = mutableSetOf<String>()
setOf.add("set_a")
setOf.add("set_b")
setOf.add("set_c")
setOf.add("set_b")
setOf.forEach {
if (it == "set_a") Log.e("fffpzf", "擷取到:set_a") else Log.e("fffpzf", "我是:$it")
}
var index = setOf.indexOfFirst {
//找到第一個叫set_b的下表
it.startsWith("set_b")
}
Log.e("fffpzf","第一個set_b下表:$index")
val str=setOf.find {
it.startsWith("set")
}
Log.e("fffpzf","找到第一個set開頭的全名:$str")
setOf.filter {
//過濾
}
setOf.sortedBy {
//排序
}
setOf.groupBy {
//分組
}
}
經驗:
上面是一些lambda表達式,其實就是這些都是最後一個參數是閉包,閉包中用it來辨別自身,是以為什麼setOf.find{}中的
it.startWith("set")為什麼可以用it,這個就是自身setIOf。
Ps:我是在飛~~,隻有空閑時間才能更新部落格,是以本系列偏快速入門,主要講實戰中經常用到内容,讓你快速上手。是以文章盡量簡短,敬請諒解,本系列文章預設閱讀者已經熟悉java語言,希望我的部落格對你有幫助!
相關源碼
有問題可聯系q:1660380990郵箱[email protected]