Kotlin中的內建函式-apply、let

語言: CN / TW / HK

持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第19天,點選檢視活動詳情

在使用Kotlin的過程中會經常用到其內建函式,包括apply,let,run,with,also,takeIf,takeUnless函式等,想要更好熟悉Kotlin,這些函式必須爛熟於心,接下來讓我們來逐步瞭解:

apply函式

apply函式,屬於內聯擴充套件函式,其擴充套件了所有的泛型物件,在閉包範圍內可以任意呼叫該物件的任意方法,並在最後返回該物件。也許看到這裡你並沒有太瞭解,接下來讓我們從簡單程式碼入手: fun main(){ val tips = "Hello this world" println("tips的字串長度為:${tips.length}") println("tips的最後一個字元為:${tips[tips.length-1]}") println("tips全部置換大小寫:${tips.lowercase()}") } 這段函式很簡單,定義一個字串然後分別列印,對應輸出結果為:

image.gif 我們加入apply函式,一般情況下,匿名函式都會持有一個it,但是apply函式沒有持有it,而是持有當前this,在這裡this = tips本身。我們在原函式中加入對this的引用邏輯,例如以下: fun main(){ val tips = "Hello this world" println("tips的字串長度為:${tips.length}") println("tips的最後一個字元為:${tips[tips.length-1]}") println("tips全部置換大小寫:${tips.lowercase()}") tips.apply { println(this) } } 對應的列印為: image.gif 可見,最後列印的this即是tips本身,而在apply中this又可以省略,我們修改列印到對應的apply函式中,則原始碼變為以下: fun main(){ val tips = "Hello this world" println("tips的字串長度為:${tips.length}") println("tips的最後一個字元為:${tips[tips.length-1]}") println("tips全部置換大小寫:${tips.lowercase()}") println("---------------------------------------") tips.apply { println(this) println("tips的字串長度為:${length}") println("tips的最後一個字元為:${this[length-1]}") //這裡最外面的this不能省(Collection literals outside of annotations) println("tips全部置換大小寫:${this.lowercase()}") } } 其對應輸出結果為:

image.gif 這些不難理解,所以這裡我們可以說apply函式擴充套件的是其物件,同時還能返回生成此物件。那麼問題來了,我要這函式有何用?一個語言不可能白設計一個沒有作用的函式。比如我們通常宣告一個檔案,還要同時宣告此檔案一些特點時: val file = File("C:\\HelloWorld.java") file.setReadable(true) file.setReadOnly() 這樣修改為: val file = File("C:\\HelloWorld.java") file.apply { setReadable(true) }.apply { setReadOnly() } 由於apply函式能返回原物件,所以也支援鏈式呼叫。以上程式碼在功能作用上完全等價。

let函式

屬於匿名函式型別,提供了函式式API的程式設計介面,將原始物件作為引數傳遞到表達Lamba表示式中,在閉包範圍內用it指代原物件,我們還是通過例項來加深理解,先來一段簡單函式: val list = listOf(1, 2, 3, 4, 5, 6) val first = list.first() println(first+first) 程式碼不難理解,可預見輸出結果為:

image.gif 再用let函式形式編寫如下: val result = listOf(1, 2, 3, 4, 5, 6).let { it.first()+it.first() } println("let結果為$result") 對應輸出結果為:

image.gif 可見,let函式所返回的物件,是在函式中執行完的物件,即let函式的返回型別是根據匿名函式最後一行的變化而變化的,這是跟apply函式的一個區別,apply函式返回的永遠是函式本身。例如我們新增些apply的程式碼,如下: fun main(){ val result = listOf(1, 2, 3, 4, 5, 6).let { it.first()+it.first() } val result2 = listOf(1, 2, 3, 4, 5, 6).apply { this.first()+this.first() } println("let結果為$result") println("apply結果為$result2") } 對應輸出結果為:

image.gif

總結

在這裡我們對兩個函式總結一下:

apply

1、函式返回的型別都是原泛型物件本身;

2、函式內部持有的是this,原物件本身。

Let

1、let函式所返回的物件,是在函式中執行完的物件,即let函式的返回型別是根據匿名函式最後一行的變化而變化的;

2、函式內部持有的是it。