如何将Kotlin的`with`表达式用于可空类型

时间:2016-03-01 12:41:30

标签: kotlin nullable with-statement

下面的代码无法编译,因为变量myType可以为null。有没有办法在Kotlin中为可空类型执行with块?

    val myType: MyType? = null
    with(myType) {
        aMethodThatBelongsToMyType()
        anotherMemberMethod()            
    }

2 个答案:

答案 0 :(得分:17)

您可以将可空类型转换为带有后缀!!的非可空类型:

with(myType!!) {
    aMethodThatBelongsToMyType()
    anotherMemberMethod()            
}

如果该值确实为null,则会抛出NullPointerException,因此通常应该避免这种情况。

更好的方法是通过进行空安全调用并使用apply扩展函数而不是with来使代码块的执行依赖于非空值。 :

myType?.apply {
    aMethodThatBelongsToMyType()
    anotherMemberMethod()            
}

另一种选择是使用if语句检查值是否为非null。编译器会在if-block中插入一个非可空类型的智能转换:

if (myType != null) {
    with(myType) {
        aMethodThatBelongsToMyType()
        anotherMemberMethod()            
    }
}

答案 1 :(得分:2)

您可以定义自己接受nullables的with函数,然后根据对象是否为null来确定是否实际运行。

像这样:

fun <T, R> with(receiver: T?, block: T.() -> R): R? {
    return if(receiver == null) null else receiver.block()
}

然后,您可以在示例中按照您想要的方式调用代码而不会出现任何问题,如果您传入的内容为null,则结果将等于null

或者,如果代码块应该(并且可能)以任何一种方式运行,即使myTypenull,那么您也可以这样定义它:

fun <T, R> with(receiver: T?, block: T?.() -> R): R {
    return receiver.block()
}