kotlin with、let、run、also、apply

以下通过AlertDialog构建使用案例

创建AlertDialog.Builder()

val builder = AlertDialog.Builder(this)
let()

为了方便省去确定、取消按钮

builder.let {
            it.setTitle("Dialog title")
            it.setMessage("Dialog message")
            it.setCancelable(false)
            it.show()
        }

看上去和java的链式调用并无很大区别,也省略不了多少代码。实则当调用let函数的对象为可空类型时更加方便,相当于少写一个if != null的判断。使用场景为单个对象的多次方法调用,可空对象使用起来更加舒适。

builder?.let {
            it.setTitle("Dialog title")
            it.setMessage("Dialog message")
            it.setCancelable(false)
            it.show()
        }

点进去看let函数实现

public inline fun  T.let(block: (T) -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block(this)
}

let函数是T类型的扩展函数,任意对象都可调用。参数为lambda,将调用者对象T传到lambda,所以lambda中it指向调用者,函数返回值即lambda返回值。

run()
public inline fun  T.run(block: T.() -> R): R {
    return block()
}

与let函数的区别在于参数block: T.() -> R是带接收者的lambda,lambda内部this指向接收者T。

builder.run {
            setTitle("Dialog title")
            setMessage("Dialog message")
            setCancelable(false)
            show()
        }

相较于let函数,省略了it,适用于任何let函数使用的场景。

also()
public inline fun  T.also(block: (T) -> Unit): T {
    block(this)
    return this
}

与let函数的区别:函数的返回值为T,即调用者本身。适用于任何let函数使用的场景,并且返回调用者对象本身。

val builder = builder.also {
            it.setTitle("Dialog title")
            it.setMessage("Dialog message")
            it.setCancelable(false)
            it.show()
        }
apply()
public inline fun  T.apply(block: T.() -> Unit): T {
    block()
    return this
}

与also函数的区别:block: T.() -> Unit带接收者的lambda,可省略it。适用于任何also函数使用的场景。

val builder = builder.apply {
            setTitle("Dialog title")
            setMessage("Dialog message")
            setCancelable(false)
            show()
        }
with()
public inline fun  with(receiver: T, block: T.() -> R): R {
    return receiver.block()
}

with函数有两个参数,T和带有接收者T的lambda。return receiver.block()函数内部T调用了lambda,函数返回值为lambda返回值;等同于run函数,只是写法稍有区别。

with(builder){
            setTitle("Dialog title")
            setMessage("Dialog message")
            setCancelable(false)
            show()
        }
配合扩展函数使用

定义两个扩展函数

inline fun Activity.initDialog(block: AlertDialog.Builder.() -> Unit) =
    AlertDialog.Builder(this).run { block(this) }

inline fun Fragment.initDialog(block: AlertDialog.Builder.() -> Unit) = this.context?.run {
    AlertDialog.Builder(this).run { block(this) }
}

Activity中调用

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initDialog {
            setTitle("Dialog title")
            setMessage("Dialog message")
            setCancelable(false)
            show()
        }
}

你可能感兴趣的:(kotlin with、let、run、also、apply)