Разница между!! а также? в Котлине
Я новичок в Kotlin. Я хочу знать разницу между этими двумя !!
и ?
в приведенном ниже коде.
У меня есть ниже двух фрагментов, сначала использующих !!
для mCurrentDataset, а другой - ?
для той же переменной.
if(!mCurrentDataset!!.load(mDataSetString.get(mCurrentDataSelectionIndex), STORAGE_TYPE.STORAGE_APPRESOURCE))
{
Log.d("MyActivity","Failed to load data.")
return false
}
if(!mCurrentDataset?.load(mDataSetString.get(mCurrentDataSelectionIndex), STORAGE_TYPE.STORAGE_APPRESOURCE)!!)
{
Log.d("MyActivity","Failed to load data.")
return false
}
Спасибо заранее.
Ответы
Ответ 1
Как сказано в ссылка Kotlin, !!
является опцией для любителей NPE:)
a!!.length
вернет ненулевое значение a.length
или выбросит NullPointerException, если a
is null
:
val a: String? = null
print(a!!.length) // >>> NPE: trying to get length of null
a?.length
возвращает a.length
, если a
не null
, а null
иначе:
val a: String? = null
print(a?.length) // >>> null is printed in the console
Подводя итог:
+------------+--------------------+---------------------+----------------------+
| a: String? | a.length | a?.length | a!!.length |
+------------+--------------------+---------------------+----------------------+
| "cat" | Compile time error | 3 | 3 |
| null | Compile time error | null | NullPointerException |
+------------+--------------------+---------------------+----------------------+
Может быть полезно: Что такое NullPointerException?
Ответ 2
это '!!' оператор double-bang всегда возвращает не-нулевое значение, и это '?' оператор безопасного вызова возвращает значение, если значение не равно null, а null в противном случае
Это небезопасное преобразование типа NULL (T?) в непустой тип (T). Он выкинет NullPointerException, если значение равно null.
Документировано здесь вместе с средствами Kotlin нулевой безопасности.
ref - горячая клавиша
Ответ 3
приоритет операторов !
, ?.
, !!
равен ?.
> !!
> !
.
оператор !!
будет поднимать KotlinNullPointerException
при работе с ссылкой null
, например:
null!!;// raise NullPointerException
оператор безопасного вызова ?.
возвращает null
при работе с ссылкой null
, например:
(null as? String)?.length; // return null;
оператор !!
в вашем втором подходе может поднять NullPointerException
, если левая сторона null
, например:
mCurrentDataset?.load(..)!!
^-------------^
|
when mCurrentDataset== null || load() == null a NullPointerException raised.
вы можете использовать оператор elvis ?:
вместо оператора !!
в вашем случае, например:
!(mCurrentDataset?.load(..)?:false)