mem*_*izr 11 nullable with-statement kotlin
下面的代码将无法编译,因为该变量myType
可以为null.有没有办法with
在Kotlin中为可空类型执行块?
val myType: MyType? = null
with(myType) {
aMethodThatBelongsToMyType()
anotherMemberMethod()
}
Run Code Online (Sandbox Code Playgroud)
Ing*_*gel 17
您可以使用后缀将可空类型转换为非可空类型!!
:
with(myType!!) {
aMethodThatBelongsToMyType()
anotherMemberMethod()
}
Run Code Online (Sandbox Code Playgroud)
如果该值确实为null,则会抛出一个NullPointerException
,因此通常应该避免这种情况.
更好的方法是通过进行空安全调用并使用apply
扩展函数代替以下内容来使代码块的执行依赖于非空值with
:
myType?.apply {
aMethodThatBelongsToMyType()
anotherMemberMethod()
}
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用if
语句检查值是否为非null .编译器会将智能强制转换插入if块中的非可空类型:
if (myType != null) {
with(myType) {
aMethodThatBelongsToMyType()
anotherMemberMethod()
}
}
Run Code Online (Sandbox Code Playgroud)
您可以定义自己的with
函数来接受可空值,然后根据对象是否为空来确定是否实际运行。
像这样:
fun <T, R> with(receiver: T?, block: T.() -> R): R? {
return if(receiver == null) null else receiver.block()
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以按照示例中您想要的方式调用代码,没有任何问题,并且null
如果您传入的是 ,结果将相等null
。
或者,如果代码块应该(并且可以)以任何一种方式运行,即使是myType
,null
那么您也可以像这样定义它:
fun <T, R> with(receiver: T?, block: T?.() -> R): R {
return receiver.block()
}
Run Code Online (Sandbox Code Playgroud)