[toc]
了解內(nèi)聯(lián)函數(shù)前先了解下lambda表達(dá)式
lambda
Lambda表達(dá)式的本質(zhì)其實(shí)是匿名函數(shù)栓袖,因?yàn)樵谄涞讓訉?shí)現(xiàn)中還是通過(guò)匿名函數(shù)來(lái)實(shí)現(xiàn)的。但是我們?cè)谟玫臅r(shí)候不必關(guān)心起底層實(shí)現(xiàn)店诗。不過(guò)Lambda的出現(xiàn)確實(shí)是減少了代碼量的編寫裹刮,同時(shí)也是代碼變得更加簡(jiǎn)潔明了。
使用
1. 無(wú)參數(shù)的情況 :
val/var 變量名 = { 操作的代碼 }
2. 有參數(shù)的情況
val/var 變量名 : (參數(shù)的類型庞瘸,參數(shù)類型捧弃,...) -> 返回值類型 = {參數(shù)1,參數(shù)2擦囊,... -> 操作參數(shù)的代碼 }
可等價(jià)于
// 此種寫法:即表達(dá)式的返回值類型會(huì)根據(jù)操作的代碼自推導(dǎo)出來(lái)违霞。
val/var 變量名 = { 參數(shù)1 : 類型,參數(shù)2 : 類型, ... -> 操作參數(shù)的代碼 }
3. lambda表達(dá)式作為函數(shù)中的參數(shù)的時(shí)候瞬场,這里舉一個(gè)例子:
fun test(a : Int, 參數(shù)名 : (參數(shù)1 : 類型买鸽,參數(shù)2 : 類型, ... ) -> 表達(dá)式返回類型){
...
}
實(shí)例講解
- 無(wú)參數(shù)的情況
// 源代碼
fun test(){ println("無(wú)參數(shù)") }
// lambda代碼
val test = { println("無(wú)參數(shù)") }
// 調(diào)用
test() => 結(jié)果為:無(wú)參數(shù)
- 有參數(shù)的情況
// 源代碼
fun test(a : Int , b : Int) : Int{
return a + b
}
// lambda
val test : (Int , Int) -> Int = {a , b -> a + b}
// 或者
val test = {a : Int , b : Int -> a + b}
// 調(diào)用
test(3,5) => 結(jié)果為:8
- lambda表達(dá)式作為函數(shù)中的參數(shù)的時(shí)候
// 源代碼
fun test(a : Int , b : Int) : Int{
return a + b
}
fun sum(num1 : Int , num2 : Int) : Int{
return num1 + num2
}
// 調(diào)用
test(10,sum(3,5)) // 結(jié)果為:18
// lambda
fun test(a : Int , b : (num1 : Int , num2 : Int) -> Int) : Int{
return a + b.invoke(3,5)
}
// 調(diào)用
test(10,{ num1: Int, num2: Int -> num1 + num2 }) // 結(jié)果為:18
T.()->Unit 、 ()->Unit的區(qū)別
- ()->Unit與(T) -> Unit是相同的贯被,是lambda的函數(shù)參數(shù)形式眼五,只是一個(gè)帶參,一個(gè)不帶參彤灶。(T) -> Unit通過(guò)形參T可將對(duì)象作為實(shí)參傳給函數(shù)看幼,所以函數(shù)體里能通過(guò)it或者指定名稱的方式來(lái)訪問(wèn)該對(duì)象
- T.()->Unit 等同于為T定義了一個(gè)無(wú)參數(shù)的擴(kuò)展函數(shù),所以在函數(shù)體內(nèi)可以直接通過(guò)this或省略來(lái)訪問(wèn)T代表的對(duì)象
實(shí)例講解
(T) -> Unit
fun Person.alsoWithReceiver(block:(Person) ->Unit):Person{
block(this)
return this
}
//構(gòu)造的參數(shù)是it
person.alsoWithReceiver {
it.setNewName("haha bro")
}.getOldName()
T.()->Unit
fun Person.ApplyNew(block:Person.() ->Unit):Person{
block()
return this
}
//構(gòu)造的參數(shù)是this
person.ApplyNew {
this.setNewName("aa")
}
1.Let
1.1作用
- 使用it替代object對(duì)象去訪問(wèn)其公有的屬性 & 方法
- 判斷object為null的操作
1.2底層結(jié)構(gòu)
public inline fun <T, R> T.let(block: (T) -> R): R {
return block(this)
}
1.3使用方法
// 作用1:使用it替代object對(duì)象去訪問(wèn)其公有的屬性 & 方法
object.let{
it.todo()
}
// 作用2:判斷object為null的操作
object?.let{//表示object不為null的條件下幌陕,才會(huì)去執(zhí)行l(wèi)et函數(shù)體
it.todo()
}
// 注:返回值 = 最后一行 / return的表達(dá)式
1.4實(shí)例講解
// 使用Java
if( mVar != null ){
mVar.function1();
mVar.function2();
mVar.function3();
}
// 使用kotlin(無(wú)使用let函數(shù))
mVar?.function1()
mVar?.function2()
mVar?.function3()
// 使用kotlin(使用let函數(shù))
// 方便了統(tǒng)一判空的處理 & 確定了mVar變量的作用域
mVar?.let {
it.function1()
it.function2()
it.function3()
}
2.Also
2.1作用
類似let函數(shù)诵姜,但區(qū)別在于返回值:
let函數(shù):返回值 = 最后一行 / return的表達(dá)式
also函數(shù):返回值 = 傳入的對(duì)象的本身
2.2底層結(jié)構(gòu)
public inline fun <T> T.also(block: (T) -> Unit): T {
block(this)
return this
}
2.3使用方法
// 作用1:使用it替代object對(duì)象去訪問(wèn)其公有的屬性 & 方法
object.also{
//this 可省略
this.todo()
}
// 作用2:判斷object為null的操作
object?.also{//表示object不為null的條件下,才會(huì)去執(zhí)行l(wèi)et函數(shù)體
todo()
}
2.4實(shí)例講解
// let函數(shù)
var result = mVar.let {
it.function1()
it.function2()
it.function3()
999
}
// 最終結(jié)果 = 返回999給變量result
// also函數(shù)
var result = mVar.also {
it.function1()
it.function2()
it.function3()
999
}.todo()
// 最終結(jié)果 = 返回一個(gè)mVar對(duì)象給變量result
3.with
3.1作用
調(diào)用同一個(gè)對(duì)象的多個(gè)方法 / 屬性時(shí)搏熄,可以省去對(duì)象名重復(fù)棚唆,直接調(diào)用方法名 / 屬性即可
3.2底層結(jié)構(gòu)
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
return receiver.block()
}
3.3使用方法
with(object){
// ...
}
// 返回值 = 函數(shù)塊的最后一行 / return表達(dá)式
3.4 使用示例
3.4實(shí)例講解
// 此處要調(diào)用people的name 和 age屬性
// kotlin
val people = People("carson", 25)
with(people) {
this.setName("zhangsan")
setAge(15)
println("my name is $name, I am $age years old")
}
// Java
User peole = new People("carson", 25);
String var1 = "my name is " + peole.name + ", I am " + peole.age + " years old";
System.out.println(var1);
4.Run
4.1作用
結(jié)合了let、with兩個(gè)函數(shù)的作用搬卒,即:
1. 調(diào)用同一個(gè)對(duì)象的多個(gè)方法 / 屬性時(shí)瑟俭,可以省去對(duì)象名重復(fù),直接調(diào)用方法名 / 屬性即可
2. 定義一個(gè)變量在特定作用域內(nèi)
3. 統(tǒng)一做判空處理
4.2底層結(jié)構(gòu)
public inline fun <T, R> T.run(block: T.() -> R): R {
return block()
}
4.3使用方法
object.run{
// ...
}
// 返回值 = 函數(shù)塊的最后一行 / return表達(dá)式
4.4實(shí)例講解
// 此處要調(diào)用people的name 和 age屬性契邀,且要判空
// kotlin
val people = People("carson", 25)
people?.run{
println("my name is $name, I am $age years old")
}
// Java
User peole = new People("carson", 25);
String var1 = "my name is " + peole.name + ", I am " + peole.age + " years old";
System.out.println(var1);
5.Apply
5.1作用
與run函數(shù)類似摆寄,但區(qū)別在于返回值:
1. run函數(shù)返回最后一行的值 / 表達(dá)式
2. apply函數(shù)返回傳入的對(duì)象的本身
5.2底層結(jié)構(gòu)
public inline fun <T> T.apply(block: T.() -> Unit): T {
block()
return this
}
5.3使用方法
object.apply{
// ...
}
// 返回值 = object
5.4實(shí)例講解
// run函數(shù)
val people = People("carson", 25)
val result = people?.run{
println("my name is $name, I am $age years old")
999
}
// 最終結(jié)果 = 返回999給變量result
// Java
val people = People("carson", 25)
val result = people?.run{
println("my name is $name, I am $age years old")
999
}
// 最終結(jié)果 = 返回一個(gè)people對(duì)象給變量result