让Kotlin帮助我避免一些if(null?)doSomething。
但是我有问题。
A是对象的字段,而B是对象A的字段。它们可以是空包。
他们在这样的代码中。
class Obj {
var a : A?
}
class A {
var b : B?
}
我知道我可以通过双重租赁来做到这一点:
A?.let {
it.B.let {
// a must nonnull
}
}
A?.B?.let {
// how to use A ,without null check again?
}
答案 0 :(得分:3)
有扩展功能可以实现所需的功能,您可以在此线程https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946中找到它们
但是,老实说,最好在这里使用基本的if检查,如果变量是可变的,则可以先将其分配给val
。
val _a = a
val _b = b
if (_a != null && _b != null) {
}
编辑:如果您仍然想使用let,在这种情况下,您可以创建一个配对并使用takeIf
(a to b)
.takeIf { (a, b) ->
a != null && b != null
}
?.let { (a, b) ->
}
但是,编译器不会将值智能广播为非空值,因此您仍然必须对它们执行非空(!!)断言。
答案 1 :(得分:2)
默认情况下,Kotlin避免使用null
的值,而对于Null Safety
,它提供了:
1)安全呼叫接线员(?。)
2)非空断言(!!)
3)猫王Opeartor(?:)
4)使用let(?.let {...})
安全呼叫操作员(?。):在执行任何操作之前检查属性是否不为空。
非空断言(!!):明确告诉编译器该属性不为null,如果为null,请抛出null指针异常(NPE)
Elvis Opeartor(?:):就像Java中的三元运算符。如果property不为null,则返回left表达式,否则返回right。
带有let(?.let {...})的安全调用:仅当属性不为null时,才会执行let块
一个示例(属性内含非空值):
fun main() {
val name: String? = "Sumit"
println("Safe Call operator: ${name?.length}")
name?.let {
println("Safe Call wih let operator: ${name.length}")
}
val length = name?.length ?: 0
println("Elvis operator : $length")
println("Not Null Assertion Operator : ${name!!.length}")
}
输出(属性内部具有非空值)
安全呼叫接线员:5
让操作员安全呼叫:5
猫王运算符:5
非空声明运算符:5
输出(属性中带有空值)(值名称:字符串?= null)
Safe Call operator: null
Elvis operator : 0
Exception in thread "main" kotlin.KotlinNullPointerException
at HelloKt.main(Hello.kt:14)
at HelloKt.main(Hello.kt)
在这里,不执行带有let的安全呼叫!!非空断言运算符会引发空指针异常。
您的问题可以使用非null断言运算符:
A?.B?.let { // If A and B are not null then only this block will be executed. A.someMethod() B.someMethod() }
答案 2 :(得分:1)
您可以像使用精灵操作员?:
fun doSomething() {
val a = A ?: return
val b = B ?: return
doSomethingWith(a, b)
}
这里a
和b
是对您所保存数据的不可空引用,在这种情况下,您只需从函数中返回即可。
答案 3 :(得分:0)
另一种选择是写这样的东西
fun <A, B> A?.and(that: B?, block: (A, B) -> Unit) {
this?.let { a -> that?.let { b -> block(a, b) } }
}
然后像这样使用它
var first: Int?
var second: Int?
first.and(second) { f, s -> someFunction(f,s) }
答案 4 :(得分:0)
您可以将when用作多个变量的or或语句
when(null) {
a, b -> return //for your case of nested properties try something like "obj.a, obj?.a?.b"
else -> doSomethingWhenAAndBAreNotNull()
}
//or do something when a and b are not null here so you don't need to nest