Що таке оператор Котліна з подвійним ударом (!!)?


177

Я перетворюю Java на Kotlin за допомогою Android Studio. Я отримую подвійний удар після змінної екземпляра. Що таке подвійний удар і, що важливіше, де це документально підтверджено?

mMap!!.addMarker(MarkerOptions().position(london).title("Marker in London"))

Відповіді:


205

Це небезпечне T?перетворення нульового типу ( ) в ненульовий тип ( T), !!буде кинутим, NullPointerExceptionякщо значення є null.

Це задокументовано тут, поряд із засобами нульової безпеки Котліна.


1
що це означає, коли !!знак знаходиться в кінці заяви? Автоперетворення IJ в Котлін зробив це для менеval price = sale.latest!!
ycomp

7
@ycomp, це означає, що sale.latestможе містити null; призначення буде успішним лише в тому випадку, якщо sale.latestвоно не є нульовим і в іншому випадку викине NPE. Це дає нульову безпеку для val price: його тип буде ненульовим. Дивіться kotlinlang.org/docs/reference/null-safety.html
гаряча клавіша

1
@hotkey: Тож у чому різниця між отриманням NPE - тут АБО коли доступ до останнього методу здійснюється на нульовому об’єкті?
Аада

2
@Aada, загальною проблемою є налагодження NPE і важко знаходити шлях / рядок виконання, який встановив значення нульовим. Це нульове призначення може статися в іншому контексті, класі чи навіть у день! Використовуючи, !!ви можете швидко вийти з ладу та знайти першопричину NPE. Я хотів би, щоб у Java була подібна особливість (тобто без потворних ifтверджень та / або assertіонів).
Каскадер

82

Ось приклад, щоб зробити речі зрозумілішими. Скажіть, у вас є ця функція

fun main(args: Array<String>) {
    var email: String
    email = null
    println(email)
}

Це призведе до наступної помилки компіляції.

Null can not be a value of a non-null type String

Тепер ви можете запобігти цьому, додавши знак питання до Stringтипу, щоб зробити його незмінним.

Так ми маємо

fun main(args: Array<String>) {
    var email: String?
    email = null
    println(email)
}

Це дає результат

null

Тепер, якщо ми хочемо, щоб функція видала виняток, коли значення електронної пошти є нульовим, ми можемо додати два вигуки в кінці електронної пошти. Подобається це

fun main(args: Array<String>) {
    var email: String?
    email = null
    println(email!!)
}

Це кине а KotlinNullPointerException


5
Отже, чому б люди вживали "!!" навіть якщо це небезпечно, оскільки додаток буде припинено, коли ця змінна має нульовий характер?
Сем

3
@david, ви можете використовувати його лише тоді, коли ви на 100% впевнені, що змінна не є нульовою (наприклад, ви явно перевірили її) і вам потрібна незмінна змінна
FMK

7
@FMK Я розумію, дякую! Я розумію, що подвійний вибух використовується для того, щоб значення змінної типу nullable переходили в змінну ненульових типів, правда?
Сем

2
@david так, точно.
FMK

10

Оператор подвійного вибуху - відмінний варіант для любителів NullPointerException(або NPE для коротких).

Оператор твердження не-NULL !! перетворює будь-яке значення до типу ненульового і генерує виняток , якщо значення дорівнює нулю.

val nonNull = a!!.length

Таким чином, ви можете написати a!!, і це поверне ненулеве значення a( Stringнаприклад, тут) або викине NPE, якщо воно aє нульовим.

Якщо ви хочете NPE, ви можете мати його, але ви повинні прямо просити його. Цей оператор слід використовувати в тих випадках, коли розробник гарантує - значення ніколи не буде нульовим .


2
Питання як початківець: чому я хотів би перетворити будь-яке значення в ненульовий тип?
Wolf359

4
@ Wolf359 Це дозволяє бути на 100% впевненим, що його значення не є нульовим. ("загальною проблемою є налагодження NPE і важко знаходити шлях / рядок виконання, який встановлює значення" null ". Це присвоєння нулю може статися в іншому контексті, класі або навіть в день!" Cascader)
зменшення активності
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.