在下面的代码中,在减去两个字段之前,会对它们进行 null 检查:
if ((testingStartTime != null) && (testingEndTime != null))
summary.duration = testingEndTime!!.time - testingStartTime!!.time
是否可以以某种方式删除非空断言运算符!!
以执行减法?更好的方法是执行上述代码而不检查 if 语句中是否两者都不为 null。
似乎您将 testingStartTime 和 testingEndTime 声明为可变变量 (var(,因此无法将智能转换为不可为空的类型。有两种惯用方法可以解决您的问题:
-
将 testingStartTime 和 testingEndTime 声明为不可变变量 (val((如果可能(
-
创建这些变量的两个本地不可变副本,并使用它们来实现智能转换:
val startTime = testingStartTime
val endTime = testingEndTime
if ((startTime != null) && (endTime != null))
summary.duration = endTime.time - startTime.time
你可以这样做:
summary.duration = testingEndTime?.let { endTime ->
testingStartTime?.let { startTime ->
endTime - startTime
}
}
这将起作用,但如果testingEndTime
或testingStartTime
null
,则会null
分配给summary.duration
.如果需要null
任一从属值时的默认值,则可以执行以下操作:
summary.duration = testingEndTime?.let { endTime ->
testingStartTime?.let { startTime ->
endTime - startTime
}
} ?: 0
或者,如果其中一个相关值为 null,则根本不想更改summary.duration
的值,您可以执行以下操作:
summary.duration = if (testingEndTime != null && testingStartTime != null) {
testingEndTime - testingStartTime
} else {
summary.duration
}
这个怎么样:
fun main() {
val x: Int? = null
val y: Int? = 5
val z = x-y
print(z)
}
operator fun Int?.minus(x: Int?) : Int? {
this ?: return null
x ?: return null
return this-x
}
我知道这是太多的代码,但它可能在多个地方使用。
如果简洁性对您很重要,则可以组合交替使用接收器或参数的作用域函数,这样就不必命名参数。可读性可能值得怀疑。
testingStartTime?.let { testingEndTime?.run { summary.duration = it.time - this.time } }
或
summary.duration = testingStartTime?.let { testingEndTime?.run { it.time - this.time } }
?: summary.duration
只是为了好玩,你可以这样做:
operator fun Double?.minus(other: Double?) =
if (this == null || other == null) null else this - other
然后使用
summary.duration = (testingStartTime?.time - testingEndTime?.time)?: summary.duration
但不建议重载基元的运算符,因为它可能会使代码在其他地方难以辨认。
您已经事先检查了空值,因此理想情况下不需要!!
。
Kotlin 通常会将这些变量智能转换为非空类型,但这可能会被阻止,因为它们是可变的类属性。
要解决此问题,只需将它们分配给局部变量:
val start = testingStartTime
val end = testingEndTime
if (start != null && end != null) {
summary.duration = start.time - end.time
}
这与您的代码具有相同的行为,是的,使用更多行,但在我看来看起来更干净。如果你真的不喜欢重新分配变量,你也可以将它们作为函数参数传递。