让kotlin在kotlin中帮助我避免(null?(dosomething。
但是我有问题。
a是对象的字段,b是对象A的字段。它们可以是nullbale。
他们在这样的代码中。
class Obj {
var a : A?
}
class A {
var b : B?
}
我知道我可以通过double Let:
做到这一点A?.let {
it.B.let {
// a must nonnull
}
}
A?.B?.let {
// how to use A ,without null check again?
}
有扩展功能可以实现所需的目标,您可以在此线程中找到它们https://discuss.kotlinlang.org/t/kotlin-null-null-check - 用于毫无用的瓦尔瓦尔/1946
,但老实说,您可能会更好地使用基本如果在此处检查基本,则如果变量可变,则可以将其分配给val
。
val _a = a
val _b = b
if (_a != null && _b != null) {
}
编辑:如果您仍然真正想使用,那么,对于这种情况,您可以创建一对并使用takeIf
(a to b)
.takeIf { (a, b) ->
a != null && b != null
}
?.let { (a, b) ->
}
但是,编译器不会将值智能播放为非挂钩,因此您仍然必须对它们执行非挂钩(!!(断言。
您可以像 swift guard一样用猫王 ?:
fun doSomething() {
val a = A ?: return
val b = B ?: return
doSomethingWith(a, b)
}
此处的a
和b
是您在这种情况下持有的数据的不可删除的引用。
默认情况下kotlin避免null
值,对于Null Safety
,它提供了:
1(安全致电操作员(?。(
2(没有无效断言(!!(
3(猫王opeartor(?:(
4(let(?let {...}(
安全呼叫操作员(?。(:检查属性在执行任何操作之前是否未null。
not-null断言(!!(:明确地告诉编译器该属性不是零,如果是零,请扔一个null指针异常(NPE(
elvis opeartor(?:(:就像java中的三元运算符一样。如果属性不是null,则返回左表示。
let(?let {...}(安全呼叫:仅当属性不为null null
时,它才会执行Let Block
示例在属性中没有零值:
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}")
}
output(属性内的无零值(
安全电话操作员:5
安全致电WIH让操作员:5
猫王操作员:5
不是零断言操作员:5
output(属性中的空值((val名称:字符串?= 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)
在这里,安全打电话没有执行!和非杀伤断言操作员抛出无指针异常。
您的问题可以使用不播放断言操作员:
A?.B?.let { // If A and B are not null then only this block will be executed. A.someMethod() B.someMethod() }
您可以在多个变量的情况下用作或语句时使用
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
另一个选项可能是写类似的东西
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) }