Kotlin 13 作用域函式

2021-10-01 12:24:46 字數 4897 閱讀 4213

目錄

1、定義

2、作用

3、函式:run

4、函式:let

5、函式:also

6、函式:takeif

7、函式:takeunless

8、函式:with

9、總結

物件的擴充套件函式。

如下圖:1、紅色框內的就是pig物件所能呼叫的擴充套件函式(這些擴充套件函式對所有物件都適用)

2、綠色框內就是run擴充套件函式的原始碼,具體講解這個擴充套件函式的作用

可以在這些擴充套件函式中,對該物件進行進一步的處理。

它的作用就是將這個函式所得到的值進行返回。

fun main() 

val result2 = pig.run

val result3 = pig.run

println("result1=$result1")

println("result2=$result2")

println("result3=$result3")

}//輸出結果

result1=花姑娘長胖了

result2=330

result3=花姑娘長胖了

它的作用和run函式一樣都是對函式所得到的值進行返回。

唯一不同:它需要將呼叫let函式的物件本身,傳入到lambda閉包函式的引數中。

當然我們可以對這個引數進行簡寫(lambda只有乙個引數的話,可以省略),省略之後,如果想要呼叫自身物件的屬性可以使用it

如下:let的閉包函式的引數pig1其實就是pig本身。

val pig = pig("花姑娘", 300)

val newname = pig.let

val newname1 = pig.let

println("newname=$newname")

println("newname1=$newname1")

//輸出結果

newname=花姑娘瘦了

newname1=花姑娘瘦了

我們可以簡單可一下它的原始碼。這裡的let是乙個范型方法,t代表物件本身,r代表lambda閉包函式。

block:(t)-> r  可以看到在lambda函式中的引數就是物件本身t,

return block(this)  代表返回lambda函式的執行結果,

至於中間的 contract 它其實就是乙個契約函式,後面我們進行詳細講述。

/**

* calls the specified function [block] with `this` value as its argument and returns its result.

*/@kotlin.internal.inlineonly

public inline fun t.let(block: (t) -> r): r

return block(this)

}

它的返回物件是物件本身,所以我們可以用它對自身屬性進行一些操作,再返回本身。(類似於集合的一些操作符)

後面我附上了原始碼,可以看到return this,這個this,就是物件本身。

data class chicken(var name: string, var weight: int)

fun main() ")

this.name = "小花雞"

}println("現在的名字:$")

}//輸出結果

原來的名字:小母雞

現在的名字:小花雞

原始碼:

/** * calls the specified function [block] with `this` value as its receiver and returns `this` value.

*/@kotlin.internal.inlineonly

contract

block()

return this

}

區別:also需要將物件本身作為引數傳入到lambda函式的引數中,這個區別和run、let的區別一樣。

data class chicken(var name: string, var weight: int)

fun main() ")

chicken1.weight = 40

}println("現在的重量:$")

}//輸出結果

原來的重量:30

現在的重量:40

原始碼:/**

* calls the specified function [block] with `this` value as its argument and returns `this` value.

*/@kotlin.internal.inlineonly

@sincekotlin("1.1")

public inline fun t.also(block: (t) -> unit): t

block(this)

return this

}

//原始碼:

/** * returns `this` value if it satisfies the given [predicate] or `null`, if it doesn't.

*/@kotlin.internal.inlineonly

@sincekotlin("1.1")

public inline fun t.takeif(predicate: (t) -> boolean): t?

return if (predicate(this)) this else null

}

從原始碼可以看出,它最後返回的是根據lambda閉包函式predicate的boolean值來決定的。

如果是true就返回物件本身,

如果是false就返回null。

data class cat(var name: string, var weight: int)

fun main()

val cat2 =cat.takeif

val cat3=cat.takeif

println("cat1=$cat1")

println("cat2=$cat2")

println("cat3=$cat3")

}//輸出結果

cat1=null

cat2=cat(name=小花, weight=10)

cat3=null

它的作用和takeif一樣,不同的是它根據閉包函式predicate的boolean值返回的結果相反。

如果是true返回null,

如果是false返回物件本身。

data class cat(var name: string, var weight: int)

fun main()

val cat12 = cat.takeunless

println("cat1=$cat1")

println("cat12=$cat12")

}//輸出結果

cat1=null

cat12=cat(name=小花, weight=10)

//原始碼

/** * calls the specified function [block] with the given [receiver] as its receiver and returns its result.

*/@kotlin.internal.inlineonly

public inline fun with(receiver: t, block: t.() -> r): r

return receiver.block()

}

從原始碼我們看到它不需要物件來呼叫它,它其實是乙個頂級函式,也就shi你在**都可以呼叫這個函式。

但是它需要兩個引數,乙個是乙個物件receiver,另乙個是閉包函式block

它的返回值就是引數物件receiver對閉包函式block的呼叫結果

data class cat(var name: string, var weight: int)

fun main()

println("cat.name=$")

println("cat.weight=$")

println("result=$result")

}//輸出結果

cat.name=小白

cat.weight=11

result=2

這些作用域函式的作用還是具有很多的開放性,你可以用他們來做很多邏輯賦值操作。這就要看你的發揮了。

data class cat(var name: string, var weight: int)

fun main() .takeif ?.run

println("newname=$newname")

}//輸出結果

newname=小花+1+2+3

Kotlin作用域函式之間的區別和使用場景詳解

作用域函式 這些函式基本上做了同樣的事情 在乙個物件上執行乙個 塊。下面是作用域函式的典型用法 12 34val adam person adam adam.age 20 adam.city london println adam 作用域函式沒有引入任何新的技術,但是它們可以使你的 更加簡潔易讀。事...

函式作用域

有巢狀函式的時候有return x的返回函式x的位址,沒有的則為none def f1 n1 f1 print f1中 n1 def f2 n2 f2 def f3 n3 f3 print f3中 n3 print f2中 n2 return f3 return f2 r1 f1 print r1 ...

函式作用域

匿名函式,lambda def f o if o 7 print o print list filter lambda o o 8,4,77 22,4 8 list filter f,4,77,22,4,8 列印的話會返回none 77,22 7722 8a 5deff global a 要用全域性...