Kotlin實戰指南十:let、apply、with、run

轉載請標明出處:https://blog.csdn.net/zhaoyanjun6/article/details//94402604
本文出自【趙彥軍的博客】


let

let可以配合可空性 “?”來使用,如果data=null 則不執行let內部代碼,如果有返回值則直接返回null
let中,用it表示引用對象,並可調用其方法,it不可省略。
返回值是語句塊的最後一行的返回類型,若最後一行語句無返回值,則整個let語句塊也無返回值

示例1:基礎用法

class MainActivity : AppCompatActivity() {

    var list: ArrayList<Int>? = ArrayList()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        list?.let {
            it.add(1)
            it.add(2)
            it.add(3)
        }
        Log.e("zhaoyanjun:", "$list")
    }
}

輸出結果:

[1, 2, 3]

示例2:返回值

class MainActivity : AppCompatActivity() {

    var list: ArrayList<Int>? = ArrayList()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
      
      //let的返回值爲 let 語句塊的最後一行
       var result =  list?.let {
            it.add(1)
            it.add(2)
            it.add(3)
            "ok"
        }

        Log.e("zhaoyanjun:", "$list  $result" )
    }
}

輸出結果:

E/zhaoyanjun:: [1, 2, 3]  ok

示例3:android實戰

class MainActivity : AppCompatActivity() {

    private var tv: TextView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        tv = findViewById(R.id.tv)
        tv?.let {
            it.text = "zhaoyanjun"
            it.textSize = 20f
            it.setOnClickListener {
                Toast.makeText(it.context, "click", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

apply

apply使用this指代T,函數值返回值是Unit。但apply通過return this主動返回T的實例。

@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}

示例

創建LinearLayout並利用apply設置初始化參數,最後返回初始化完畢的LinearLayout實例。

val linearLayout = LinearLayout(itemView.context).apply {
    orientation = LinearLayout.VERTICAL
    layoutParams = LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT,
            LinearLayout.LayoutParams.WRAP_CONTENT)
}

上面的代碼等價於:

val linearLayout = LinearLayout(itemView.context)
linearLayout.orientation = LinearLayout.VERTICAL
linearLayout.layoutParams = LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.MATCH_PARENT,
        LinearLayout.LayoutParams.WRAP_CONTENT)

如果構造過程中需要初始化的變量較多,使用apply形成的代碼塊會非常直觀。

with

接收一個receiver和一個函數式,通過this調用receiver,返回值根據函數式最後一個返回值爲準。

一般會在傳入receiver的時候就地創建實例,不然使用apply來替代with會是更好的選擇。

可爲null時別和with搭檔

@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return receiver.block()
}

示例1:返回值爲一個字符串

 with(ArrayList<String>()) {
            add("a")
            add("b")
            "ok"
 }

示例2:返回值爲 this

var list = with(ArrayList<String>()) {
            add("a")
            add("b")
            this
        }

list.add("c")

run

執行傳入的函數式,並返回函數的執行結果。run的主要目的是強調需要執行的函數。

@kotlin.internal.InlineOnly
public inline fun <R> run(block: () -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}

@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}

示例

intentEXTRA_URL的值,不爲非空且內容不爲空,賦值給url。否則彈出提示並關閉頁面。

// Init url:String
url = intent.getStringExtra(EXTRA_URL)?.takeIf { it.isNotEmpty() } ?: run {
    toast("不能瀏覽一個空鏈接哦")
    activity.finish()
}

個人微信號:zhaoyanjun125 , 歡迎關注
[外鏈圖片轉存失敗(img-PqVPXCqe-1562039687164)(http://res.qiniu.zhaoaiqiao.com/weixin200.jpg)]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章