標籤:params bsp 時間 格式 lang 不同 detail rand 自動
轉自:54615036
Kotlin之let,apply,with,run函數區別重新整理
重新整理了各種函數的區別,請移步到這裡。
以下作廢
很長一段時間內都一直使用Kotlin這門語言,也只是純粹使用簡單文法,最近有時候寫的代碼,編輯器自動提示使用let等函數,然後就專門花點時間研究了下。
let
首先let()的定義是這樣的,預設當前這個對象作為閉包的it參數,傳回值是函數裡面最後一行,或者指定return
fun <T, R> T.let(f: (T) -> R): R = f(this)
簡單樣本:
fun testLet(): Int { // fun <T, R> T.let(f: (T) -> R): R { f(this)} "testLet".let { println(it) println(it) println(it) return 1 }}//運行結果//testLet//testLet//testLet
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
可以看看最後產生的class檔案,代碼已經經過格式化了,編譯器只是在我們原先的變數後面添加了let裡面的內容。
public static final int testLet() { String str1 = "testLet"; String it = (String)str1; int $i$a$1$let; System.out.println(it); System.out.println(it); System.out.println(it); return 1;}
來個複雜一定的例子
fun testLet(): Int { // fun <T, R> T.let(f: (T) -> R): R { f(this)} "testLet".let { if (Random().nextBoolean()) { println(it) return 1 } else { println(it) return 2 } }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
編譯過後的class檔案
public static final int testLet() { String str1 = "testLet"; String it = (String)str1; int $i$a$1$let; if (new Random().nextBoolean()) { System.out.println(it); return 1; } System.out.println(it); return 2;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
apply
apply函數是這樣的,調用某對象的apply函數,在函數範圍內,可以任意調用該對象的任意方法,並返回該對象
fun <T> T.apply(f: T.() -> Unit): T { f(); return this }
程式碼範例
fun testApply() { // fun <T> T.apply(f: T.() -> Unit): T { f(); return this } ArrayList<String>().apply { add("testApply") add("testApply") add("testApply") println("this = " + this) }.let { println(it) }}// 運行結果// this = [testApply, testApply, testApply]// [testApply, testApply, testApply]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
編譯過後的class檔案
public static final void testApply() { ArrayList localArrayList1 = new ArrayList(); ArrayList localArrayList2 = (ArrayList)localArrayList1; int $i$a$1$apply; ArrayList $receiver; $receiver.add("testApply"); $receiver.add("testApply"); $receiver.add("testApply"); String str = "this = " + $receiver; System.out.println(str); localArrayList1 = localArrayList1; ArrayList it = (ArrayList)localArrayList1; int $i$a$2$let; System.out.println(it); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
with
with函數是一個單獨的函數,並不是Kotlin中的extension,所以調用方式有點不一樣,返回是最後一行,然後可以直接調用對象的方法,感覺像是let和apply的結合。
fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
程式碼範例:
fun testWith() { // fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f() with(ArrayList<String>()) { add("testWith") add("testWith") add("testWith") println("this = " + this) }.let { println(it) }}// 運行結果// this = [testWith, testWith, testWith]// kotlin.Unit
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
class檔案
public static final void testWith() { Object localObject = new ArrayList(); ArrayList localArrayList1 = (ArrayList)localObject; int $i$a$1$with; ArrayList $receiver; $receiver.add("testWith"); $receiver.add("testWith"); $receiver.add("testWith"); String str = "this = " + $receiver; System.out.println(str); localObject = Unit.INSTANCE; Unit it = (Unit)localObject; int $i$a$2$let; System.out.println(it); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
run
run函數和apply函數很像,只不過run函數是使用最後一行的返回,apply返回當前自己的對象。
fun <T, R> T.run(f: T.() -> R): R = f()
程式碼範例
fun testRun() { // fun <T, R> T.run(f: T.() -> R): R = f() "testRun".run { println("this = " + this) }.let { println(it) }}// 運行結果// this = testRun// kotlin.Unit
class檔案
public static final void testRun() { Object localObject = "testRun"; String str1 = (String)localObject; int $i$a$1$run; String $receiver; String str2 = "this = " + $receiver; System.out.println(str2); localObject = Unit.INSTANCE; Unit it = (Unit)localObject; int $i$a$2$let; System.out.println(it); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
總結
怎麼樣,是不是看暈了,沒關係,我們來總結下。
函數名 |
定義 |
參數 |
傳回值 |
extension |
其他 |
let |
fun T.let(f: (T) -> R): R = f(this) |
it |
閉包返回 |
是 |
|
apply |
fun T.apply(f: T.() -> Unit): T { f(); return this } |
無,可以使用this |
this |
是 |
|
with |
fun with(receiver: T, f: T.() -> R): R = receiver.f() |
無,可以使用this |
閉包返回 |
否 |
調用方式與其他不同 |
run |
fun T.run(f: T.() -> R): R = f() |
無,可以使用this |
閉包返回 |
是 |
Kotlin之let,apply,with,run函數區別(轉)