1. 程式人生 > >Kotlin 中的 lateinit 、lazy、let 、apply 、also 、takeif、takeUnless

Kotlin 中的 lateinit 、lazy、let 、apply 、also 、takeif、takeUnless

文章目錄

前提

Kotlin和Groovy等語言一樣,支援閉包(block),如果函式中最後一個引數為閉包,那麼最後一個參可以不寫在括號中,而寫在括號後面,如果只有一個引數,括號也可以去掉。

viewPager.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

            }
       });      

那麼在 Kotlin 中,我們可以得到如下程式碼

view.setOnClickListener ({
        print("name")
    })

只有一個引數,括號可以去掉

view.setOnClickListener {
        print("name")
    }

lateinit 、by lazy

在 Kotlin 中 lateinit 和 lazy 是兩種不同的延遲初始化 技術。

  • lateinit 只用於 var,而 lazy 只用於 val

  • lazy 應用於單例模式(if-null-then-init-else-return),而且當且僅當變數被第一次呼叫的時候,委託方法才會執行。

  • lateinit 則用於只能生命週期流程中進行獲取或者初始化的變數,比如 Android 的 onCreate()

  • lateinit 只能修飾非 kotlin 基本型別,在 kotlin 中會以 null 初始化由lateinit 修飾的變數,而基礎型別沒有null 。

  • 使用 lateinit 修飾的變數,在使用時不必使用 ?!! 修飾,但是必須在第一次使用時保證為變數賦初值,不然程式會報出空指標異常。

  • 使用 by lazy 修飾的變數:

val name by lazy{
	name.....
} 

在第一次使用 name 時,會執行閉包中的程式碼對變數 name 進行初始化。

let

以當前這個物件作為閉包的 it 引數,返回值是函式裡面最後一行,或者指定 return 。

var str = listof(3,3,6)
fun main(args: Array<String>){
	str.let{
	  println(it)
	  println(it)
	  return
	}
}

列印記錄:

[3, 3, 6]
[3, 3, 6]

repeat

重複執行閉包裡面的內容

repeat(3){
   println("name")
}

列印資訊如下:

name
name
name

with

Calls the specified function block with the given receiver as its receiver and returns its result.

使用給定接收器作為接收器,呼叫指定的功能塊並返回其結果。

apply

呼叫某物件的 apply 函式,在該函式的範圍內,可以使用該物件的任意函式,並且返回該物件。

 ArrayList<Int>().apply {
        add(1)
        add(2)
        add(3)
        println(this)
    }.let { println(it) }

列印結果:

[1, 2, 3]
[1, 2, 3]

run

run 函式的使用基本和 apply 函式相同,唯一不同的是,run 函式的返回值由最後一行決定,而 apply 函式返回該物件。

ArrayList<Int>().run {
        add(1)
        add(2)
        add(3)
        println(this)
        get(1)
    }.let { println(it.toString() + "3535") }

列印日誌:

23535

also

執行閉包,返回呼叫物件 this。

ArrayList<Int>().run {
        add(1)
        add(2)
        add(3)
        println(this)
        get(1)
    }.also {
        println(it)
        it + 2
    }.let { println(it) }

執行結果

[1,2,3]
2
2

最後一個 2 的得到原因為:also 函式為執行閉包中操作後返回 this,那麼在此處 this 便是在 run 函式中返回的元素 – 2。

takeif

如果 滿足 閉包中的條件返回呼叫物件,否則返回 null 。

4.takeIf {
        it > 3
    }.let {
        println(it)
    }

執行結果

4
如果具體程式碼如下:

2.takeIf {
        it > 3
    }.let {
        println(it)
    }

則執行結果為

null

takeUnless

如果 不滿足 閉包中的條件返回呼叫物件,否則返回 null 。
與 takeif 中相同的例子,得到的結果正好是相反的。