Замена ненулевого оператора утверждения "!!" выполнить математическое выражение - PullRequest
0 голосов
/ 16 января 2020

В следующем коде проверка на нулевое значение выполняется для двух полей перед их вычитанием:

if ((testingStartTime != null) && (testingEndTime != null))
    summary.duration = testingEndTime!!.time - testingStartTime!!.time

Можно ли каким-либо образом удалить оператор ненулевого утверждения !!, чтобы выполнить вычитание? Еще лучше было бы выполнить вышеуказанный код без проверки, не являются ли оба значения в операторе if равными NULL.

Ответы [ 6 ]

2 голосов
/ 16 января 2020

Кажется, вы объявляете testStartTime и testingEndTime как изменяемые переменные (var), поэтому интеллектуальное приведение к типу, не допускающему нулевого значения, невозможно Существует два идиоматических c способа решения вашей проблемы:

  1. Объявите testingStartTime и testingEndTime в качестве неизменяемых переменных (val) (если возможно)

  2. Создайте две локальные неизменяемые копии этих переменных и работайте с ними, чтобы сделать возможным интеллектуальное приведение:

    val startTime = testingStartTime
    val endTime = testingEndTime
    if ((startTime != null) && (endTime != null))
        summary.duration = endTime.time - startTime.time
1 голос
/ 16 января 2020

Вы можете сделать это следующим образом:

summary.duration = testingEndTime?.let { endTime ->
    testingStartTime?.let { startTime -> 
        endTime - startTime
    }
}

Что бы сработало, но присвоило бы null summary.duration, если testingEndTime или testingStartTime равны 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
}
0 голосов
/ 16 января 2020

Ради интереса вы можете сделать это:

operator fun Double?.minus(other: Double?) = 
    if (this == null || other == null) null else this - other

И затем использовать

summary.duration = (testingStartTime?.time - testingEndTime?.time)?: summary.duration

Но не рекомендую перегружать операторы для примитивов, потому что это может сделать код неразборчивым в другом месте.

0 голосов
/ 16 января 2020

Если для вас важна краткость, вы можете комбинировать функции области действия, которые поочередно используют приемник или параметр, чтобы вам не приходилось называть параметры. Читаемость может быть сомнительной.

testingStartTime?.let { testingEndTime?.run { summary.duration = it.time - this.time } }

или

summary.duration = testingStartTime?.let { testingEndTime?.run { it.time - this.time } } 
    ?: summary.duration
0 голосов
/ 16 января 2020

Вы уже проверяете нулевые значения заранее, поэтому в идеале !! не нужны.

Kotlin обычно приводит к умному приведению этих переменных к ненулевым типам, но это может быть предотвращено, поскольку они являются свойствами изменяемого класса.
Чтобы исправить это, просто назначьте их локальным переменным:

    val start = testingStartTime
    val end = testingEndTime
    if (start != null && end != null) {
        summary.duration = start.time - end.time
    }

Это поведение аналогично вашему коду, и да, использует больше строк, но, на мой взгляд, выглядит чище. Если вам действительно не нравится переназначать переменные, вы можете также передать их как параметры функции, например.

0 голосов
/ 16 января 2020

Как насчет этого:

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
}

Я знаю, что это слишком много кода, но его можно использовать в разных местах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...