和...之间的不同 !!和?在Kotlin

时间:2017-06-14 05:27:55

标签: kotlin kotlin-android-extensions

我是 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
}

提前致谢。

6 个答案:

答案 0 :(得分:61)

正如Kotlin reference所述,!!是NPE爱好者的选择:)

a!!.length
如果a.lengtha

将返回非空值null或抛出 NullPointerException

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 |
+------------+--------------------+---------------------+----------------------+

可能有用:What is a NullPointerException?

答案 1 :(得分:6)

运营商!?.!!的优先级为?.> !!> !

!!运营商在对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)

答案 2 :(得分:4)

这是'!!' double-bang operator 总是返回not-null值,这是'?' 安全调用运算符如果value不为null则返回值,否则返回null

这是不安全的可空类型(T?)转换为非可空类型(T)。如果值为null,它将抛出NullPointerException。

记录here以及Kotlin无效安全手段。

参考 - hotkey

答案 3 :(得分:3)

In Addition to what Alexander said and as shown in the docs too, 

?.安全呼叫运营商在链接中非常有用,类似这样

student?.department?.hod?.name

如果没有学生,则返回null,否则寻找他的系。如果部门不存在,则返回null,否则寻找hod(部门负责人),依此类推。

如果学生,部门或学院的任何一位为空,那么结果将为空。

答案 4 :(得分:0)

SafeCall运算符(?):

var a: String = "abc"
a = null  //compile time error

val b: String? = null
val result = b?.length//returns null

断言运算符(!!):

 val b: String? = "dd" //any value or null 
 val l = b!!.length 
//this throws null pointer exception if b is null otherwise returns actual

答案 5 :(得分:0)

安全呼叫接线员

在科特林

var a = x?.length;

Java中的等效代码

int a = valueOfInt();

int valueOfInt() {
    if (x != null) {
        return x;
    } else {
        return null;
    }
}

侧链规则

bob?.department?.head?.name

它可以读为->

如果bob不为空,请给我department

如果department不为空,请给我head

如果head不为空,请给我name

如果其中任何一个为null,则返回null

?数据类型之前

如果?在数据类型之前使用:

val b: String? = null

这意味着您可以为其分配空值,否则无法为其分配空值。

!!运营商

对于那些希望在程序中具有空指针异常(NPE)的人。

val l = b!!.length

如果b不为null,则返回非null值b;如果b为null,则返回NPE。