Kotlin之let,apply,with,run函數區別

來源:互聯網
上載者:User

標籤: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)
  • 1

簡單樣本:

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;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

來個複雜一定的例子

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 }
  • 1

程式碼範例

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()
  • 1

程式碼範例:

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()
  • 1

程式碼範例

fun testRun() {    // fun <T, R> T.run(f: T.() -> R): R = f()    "testRun".run {        println("this = " + this)    }.let { println(it) }}// 運行結果// this = testRun// kotlin.Unit
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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函數區別(轉)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.