下面的代码无法编译,因为变量myType
可以为null。有没有办法在Kotlin中为可空类型执行with
块?
val myType: MyType? = null
with(myType) {
aMethodThatBelongsToMyType()
anotherMemberMethod()
}
答案 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
。
或者,如果代码块应该(并且可能)以任何一种方式运行,即使myType
是null
,那么您也可以这样定义它:
fun <T, R> with(receiver: T?, block: T?.() -> R): R {
return receiver.block()
}