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)]

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