是什么?:在Kotlin做什么? (猫王运营商)

时间:2018-01-14 19:02:06

标签: kotlin

我无法弄清?:在例如此案例中的作用

val list = mutableList ?: mutableListOf() 

为什么可以将其修改为

val list = if (mutableList != null) mutableList else mutableListOf()

9 个答案:

答案 0 :(得分:54)

TL; DR:如果生成的对象引用[first operant]不是 Route::get('/{something}/{something}', ... ,则返回它。否则返回第二个操作数(可能是null)的值

Elvis运算符是许多编程语言的一部分,例如Kotlin还有Groovy或C#。 我发现Wikipedia定义非常准确:

  

在某些计算机编程语言中, Elvis运算符 null二元运算符,如果该操作数为?:,则返回其第一个操作数,并以其他方式计算并返回其第二个操作数。它是三元条件运算符的变体true,在那些语言(以及许多其他语言)中找到:Elvis运算符是三元运算符,省略了第二个操作数

对于Kotlin来说尤其如此:

  

某些计算机编程语言对此运算符具有不同的语义。 而不是第一个操作数必须导致布尔值,它必须导致对象引用。如果生成的对象引用不是? :,则返回它。否则返回第二个操作数(可能是null)的值。

一个例子:

null

答案 1 :(得分:41)

猫王操作员由问号后跟冒号表示: ?: ,可以使用此语法:

first operand ?: second operand

它使您能够编写构造代码,并按原样运行:

如果first operand 不是,则会返回。如果为空,则会返回second operand。这可用于保证表达式不会返回空值,因为如果提供的值为null,您将提供不可为空的值。

例如(在Kotlin中):

fun retrieveString(): String {    //Notice that this type isn't nullable
    var nullableVariable: String? = getPotentialNull() //This variable may be null

    return nullableVariable ?: "Secondary Not-Null String"
}

在这种情况下,如果getPotentialNull的计算值不为空,则由retrieveString返回;如果为null,则将返回第二个表达式"Secondary Not-Null String"

另请注意,如果左侧 null ,则右侧表达式仅评估

在Kotlin中,您可以将任何表达式用作second operand,例如throw Exception表达式

return nullVariable ?: throw IllegalResponseException("My inner function returned null! Oh no!")

Elvis Operator这个名字来自美国着名歌手 Elvis Presley 。他的发型类似于问号

Elvis QuestionMark

来源:Wojda,I。Moskala,M.与Kotlin的Android开发。 2017.Packt Publishing

答案 2 :(得分:32)

这被称为Elvis operator,它确实......你在问题中描述的正是如此。如果其左侧是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

答案 3 :(得分:8)

让我们来看看Kotlin documentation

  

当我们有一个可以为空的引用r时,我们可以说"如果r不为null,请使用   它,否则使用一些非空值x":

?:(猫王)运算符可以避免冗长并使您的代码真正简洁。

例如,许多集合扩展函数返回null作为后备。

listOf(1, 2, 3).firstOrNull { it == 4 } ?: throw IllegalStateException("Ups")

?:为您提供了一种方法来处理后备案例,即使您有多层回退也是如此。如果是这样,您可以简单地将Elvis运算符链接起来,如下所示:

val l = listOf(1, 2, 3)

val x = l.firstOrNull { it == 4 } ?: l.firstOrNull { it == 5 } ?: throw IllegalStateException("Ups")

如果你用if if表达同样的东西,那么更多的代码将更难以阅读。

答案 4 :(得分:3)

考虑下面的例子,

var myStr:String? = null

//trying to find out length of myStr, but it could be null, so a null check can be put as,

val len = if (myStr != null){
    myStr.length
}
else{
    -1
}

使用elvis运算符,上面的代码可以写成一行

val len = myStr?.length ?: -1     // will return -1 if myStr is null else will return length

答案 5 :(得分:1)

Kotlin中的elvis运算符用于实现零安全。

unsafe

在上面的代码中,如果a不是x = a ?: b x的值将是a,如果null是{{1},则b的值是}。

不使用elvis运算符的等效kotlin代码如下:

a

答案 6 :(得分:1)

这是一点补充

X = A ?: B
如果Xnull都等于A

B仍将是null

因此,如果您希望X始终为non-null,请确保B始终为non-nullB的总值为{{1 }}(如果是函数或表达式)。

答案 7 :(得分:0)

基本上,如果Elvis的左侧由于某种原因返回null,则返回右侧。

val number: Int? = null
println(number ?: "Number is null")

因此,如果数字不为空,它将打印数字,否则将显示“数字为空”。

答案 8 :(得分:-1)

我们可以简单地说,您有两只手。您想知道,您的左手现在在工作吗?如果左手不起作用,则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"