Как избежать проверки гнезда 「null」 на "? .Let"? - PullRequest
1 голос
/ 26 июня 2019

пусть 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? 
}

Ответы [ 3 ]

3 голосов
/ 26 июня 2019

Существуют функции расширения для достижения того, что вы ищете, вы можете найти их в этой теме 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) {

}

Edit: Если вы все еще действительно хотите использовать let, для этого случая вы можете создать пару и использовать takeIf

(a to b)
    .takeIf { (a, b) ->
        a != null && b != null
    }
    ?.let { (a, b) ->

    }

Однако компилятор не будет передавать значения как ненулевые, поэтому вам все равно придется выполнить ненулевое (!!) утверждение для них.

2 голосов
/ 26 июня 2019

По умолчанию Kotlin избегает значений null, а для Null Safety он предоставляет:

1) Безопасный оператор вызова (?. *
2) Не пустое утверждение (!!)
3) Elvis Opeartor (?:)
4) Безопасный вызов с let (? .Let {...})

  • Безопасный вызовОператор (?.) : проверяет, не является ли свойство нулевым, перед выполнением каких-либо операций.

  • Утверждение, не являющееся нулевым (!!) : явно указываеткомпилятору, что свойство не является нулевым, и если оно является нулевым, пожалуйста, сгенерируйте исключение нулевого указателя (NPE)

  • Elvis Opeartor (?:) : Это похоже на троицуоператор в Java.Если свойство не равно NULL, то левое выражение возвращается в противном случае вправо.

  • Безопасный вызов с let (? .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
Безопасный вызов с оператором let: 5
Оператор Элвиса: 5
Оператор ненулевого подтверждения: 5

Вывод (с нулевым значением внутри свойства) (val name: String? = 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 не выполняется !!А оператор утверждения Not-Null генерирует исключение нулевого указателя.

Ваша проблема может использовать оператор утверждения не-NULL:

A?.B?.let {   
    // If A and B are not null then only this block will be executed.  
      A.someMethod()  
      B.someMethod()
}
1 голос
/ 26 июня 2019

Вы можете реализовать его как Swift охранник с оператором Элвиса ?:

fun doSomething() {
    val a = A ?: return
    val b = B ?: return
    doSomethingWith(a, b)
}

Здесь a и b являются ненулевыми ссылками на данные, которые выВ этом случае вы просто вернетесь из своей функции.

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