В следующем коде проверка на нулевое значение выполняется для двух полей перед их вычитанием:
if ((testingStartTime != null) && (testingEndTime != null))
summary.duration = testingEndTime!!.time - testingStartTime!!.time
Можно ли удалить оператор утверждения, не равный нулю !!
как-то для того, чтобы выполнить вычитание? Еще лучше был бы способ выполнить вышеупомянутый код, не проверяя, не являются ли оба значения NULL в операторе if.
Всего 6 ответов
Вы можете сделать это как:
summary.duration = testingEndTime?.let { endTime ->
testingStartTime?.let { startTime ->
endTime - startTime
}
}
Это сработало бы, но присвоило бы значение null
для summary.duration
если для параметра summary.duration
или testingEndTime
указано значение null
. Если вам нужно значение по умолчанию, когда любое из зависимых значений равно null
вы можете сделать:
summary.duration = testingEndTime?.let { endTime ->
testingStartTime?.let { startTime ->
endTime - startTime
}
} ?: 0
Или, если вы вообще не хотите изменять значение summary.duration
если любое из зависимых значений равно нулю, вы можете сделать следующее:
summary.duration = if (testingEndTime != null && testingStartTime != null) {
testingEndTime - testingStartTime
} else {
summary.duration
}
Похоже, вы объявляете testStartTime и testingEndTime как изменяемые переменные (var), поэтому интеллектуальное приведение к типу, не допускающему обнуление, невозможно. Есть два идиоматических способа решить вашу проблему:
Объявите testingStartTime и testingEndTime в качестве неизменяемых переменных (val) (если возможно)
Создайте две локальные неизменяемые копии этих переменных и работайте с ними, чтобы сделать возможным интеллектуальное приведение:
val startTime = testingStartTime
val endTime = testingEndTime
if ((startTime != null) && (endTime != null))
summary.duration = endTime.time - startTime.time
Как насчет этого:
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
}
Это похоже на ваш код, и да, использует больше строк, но, на мой взгляд, выглядит чище. Если вам действительно не нравится переназначать переменные, вы можете также передать их как параметры функции, например.