是什么?:在科特林做什么?(猫王操作员)


Answers:


115

TL; DR:如果结果对象引用[第一个操作数]不是null,则返回它。否则,null返回第二个操作数的值(可能是)


Elvis操作符是很多编程语言,如科特林而且也支持Groovy或C#的一部分。我发现Wikipedia定义非常准确:

在某些计算机编程语言中,Elvis运算符 ?:二进制运算符,如果该运算符为true,则返回其第一个操作数,否则,求值并返回其第二个操作数。这是一个三元条件运算符的变型? :在这些语言(和许多其他人)发现:Elvis操作符是三元运算符省略第二个操作数

对于Kotlin,以下情况尤其如此:

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

一个例子:

x ?: y // yields `x` if `x` is not null, `y` otherwise.

3
这真的很酷。我从未想过elvis operator可以进一步简化为其他内容。真好!很好的解释,谢谢!
sud007 '19

87

Elvis操作符由问号后面跟着冒号表示:?:并且它可以与这个语法中使用:

first operand ?: second operand

它使您能够编写简明的代码,其工作方式如下:

如果first operand 不为null,则将其返回。如果为null,则将second operand返回。这可以用来确保表达式不会返回空值,因为如果提供的值为null,则将提供非空值。


例如(在Kotlin中):

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不为null,它将由retrieveString;返回。如果为null,"Secondary Not-Null String"则将返回第二个表达式。

还要注意,当左侧为null时,才对右侧表达式求

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

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

猫王运营商这个名字来自著名的美国歌手埃尔维斯普雷斯利。他的发型像问号

猫王QuestionMark

资料来源:Wojda,I。Moskala,M。与Kotlin进行Android开发。2017. Packt出版


82
加号1,用于说明普雷斯利先生
s1m0nw1

7
?:)(以猫王微笑着看)
LeoColman

1
一段时间后,我不明白为什么将其称为猫王操作员。您的插图使我知道了为什么将其称为猫王操作员。:)
Yohanes AI

关于猫王的故事是真的吗?哈哈
Hillcow '19

@Kerooker他没有微笑,?:| 会更好的IMO。
艾哈迈德·加拉尔19-10-25

38

这叫做Elvis运算符,它确实...您在问题中所描述的正是。如果它的左手边是一个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

10
如果您来自Java,那么它更适合作为:a != null ? a : b
crgarridos

9

让我们看一下定义

当我们有一个可为空的引用r时,我们可以说“如果r不为null,则使用它,否则使用一些非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")

如果您要与其他情况表达相同的话,那么将会有更多的代码难以阅读。


3

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

喜欢这个答案。太干净了,难以理解。
Gk Mohammad Emon

2

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

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

因此,如果number不为null,它将打印数字,否则将打印“ Number为null”。


1

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

x = a ?: b

在上面的代码中,x将为aif a is notnullbif ais的值赋值null

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

x = if(a == null) b else a

1

虽然是一点点补充

X = A ?: B

X仍将null如果两个AB评估,以null

因此,如果要X始终为non-null,请确保B始终为anon-nullB始终求值为non-null它是函数还是表达式。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.