Я не можу зрозуміти, що ?:
робить, наприклад, у цьому випадку
val list = mutableList ?: mutableListOf()
і чому його можна модифікувати до цього
val list = if (mutableList != null) mutableList else mutableListOf()
Я не можу зрозуміти, що ?:
робить, наприклад, у цьому випадку
val list = mutableList ?: mutableListOf()
і чому його можна модифікувати до цього
val list = if (mutableList != null) mutableList else mutableListOf()
Відповіді:
TL; DR: Якщо отримане посилання на об'єкт [перший операнд] немає null
, воно повертається. В іншому випадку null
повертається значення другого операнда (яке може бути )
Оператор Елвіса є частиною багатьох мов програмування, наприклад Kotlin, але також Groovy або C #. Я вважаю визначення Вікіпедії досить точним:
У деяких мовах комп'ютерного програмування оператор Елвіса
?:
- це двійковий оператор, який повертає свій перший операнд, якщо цей операнд єtrue
, а в іншому випадку обчислює та повертає свій другий операнд. Це варіант трійкового умовного оператора , що? :
зустрічається в цих мовах (та багатьох інших): оператор Елвіса є потрійним оператором, а другий операнд опущений .
Для Котліна особливо справедливо наступне:
Деякі мови комп’ютерного програмування мають різну семантику для цього оператора. Замість того, щоб перший операнд мав приводити до логічного значення, він повинен приводити до посилання на об'єкт . Якщо отримане посилання на об'єкт немає
null
, воно повертається. В іншому випадкуnull
повертається значення другого операнда (яке може бути ).
Приклад:
x ?: y // yields `x` if `x` is not null, `y` otherwise.
elvis operator
може бути зведене до чогось іншого. приємно! І приємне пояснення, дякую!
Елвіс Оператор представлений знак питання слід двокрапка: ?:
і він може бути використаний з цим синтаксисом:
first operand ?: second operand
Це дозволяє вам написати код консисею і працює як такий:
Якщо first operand
значення не має значення null , його буде повернено. Якщо воно має значення null , тоді second operand
буде повернуто. Це може бути використано для гарантування того, що вираз не поверне нульового значення, оскільки ви надасте ненульоване значення, якщо надане значення є нульовим.
Наприклад (у Котліні):
fun retrieveString(): String { //Notice that this type isn't nullable
val nullableVariable: String? = getPotentialNull() //This variable may be null
return nullableVariable ?: "Secondary Not-Null String"
}
У цьому випадку, якщо обчислене значення getPotentialNull
не дорівнює нулю, воно буде повернуто до retrieveString
; Якщо воно є нульовим, "Secondary Not-Null String"
замість нього буде повернуто другий вираз .
Також зауважте, що вираз для правої сторони обчислюється лише в тому випадку, якщо ліва сторона є нульовою .
У Kotlin ви можете використовувати будь-який вираз як second operand
, наприклад, throw Exception
вираз
return nullVariable ?: throw IllegalResponseException("My inner function returned null! Oh no!")
Назва Elvis Operator походить від відомого американського співака Елвіса Преслі . Його зачіска нагадує знак запитання
Джерело: Wojda, I. Moskala, M. Android Development with Kotlin. 2017. Видавництво Packt
Це називається оператором Елвіса, і він робить ... Саме те, що ви описали у своєму питанні. Якщо його ліва сторона є null
значенням, вона повертає праву, замість цього, як запасний варіант. В іншому випадку він просто повертає значення зліва.
a ?: b
це просто скорочення для if (a != null) a else b
.
Ще кілька прикладів з типами:
val x: String? = "foo"
val y: String = x ?: "bar" // "foo", because x was non-null
val a: String? = null
val b: String = a ?: "bar" // "bar", because a was null
a != null ? a : b
Давайте подивимося на Defintion :
Коли ми маємо нульове посилання r, ми можемо сказати "якщо r не є нульовим, використовуйте його, інакше використовуйте якесь ненульове значення x":
Оператор ?:
(Елвіс) уникає багатослівності та робить ваш код справді стислим.
Наприклад, багато функцій розширення колекції повертаються null
як резервні.
listOf(1, 2, 3).firstOrNull { it == 4 } ?: throw IllegalStateException("Ups")
?:
дає вам можливість обробляти резервний випадок, навіть якщо у вас є кілька шарів резервного резервного копіювання. Якщо це так, ви можете просто помножити оператори Елвіса, як тут:
val l = listOf(1, 2, 3)
val x = l.firstOrNull { it == 4 } ?: l.firstOrNull { it == 5 } ?: throw IllegalStateException("Ups")
Якщо ви висловите те саме, якщо інакше, це буде набагато більше коду, який важче читати.
Просто ми можемо сказати це, у вас дві руки. Ви хочете знати, чи працює зараз ваша ліва рука ?. Якщо ліва рука не працює, return
empty
інакшеbusy
Приклад для Java:
private int a;
if(a != null){
println("a is not null, Value is: "+a)
}
else{
println("a is null")
}
Приклад для Kotlin:
val a : Int = 5
val l : Int = if (a != null) a.length else "a is null"
Оператор елвіса в Котліні використовується для нульової безпеки.
x = a ?: b
У наведеному вище коді x
буде присвоєно значення, a
якщо a немає, null
а b
якщо a
є null
.
Еквівалентний код kotlin без використання оператора elvis наведено нижче:
x = if(a == null) b else a