在 Kotlin 做什么

我不知道 ?:在这个例子中做了什么

val list = mutableList ?: mutableListOf()

为什么可以修改成这样

val list = if (mutableList != null) mutableList else mutableListOf()
161118 次浏览

这个叫做 猫王接线员它的功能和你在问题中描述的一模一样。如果它的左边是 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

让我们来看看 定义:

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

?:(Elvis)操作符避免了冗长,并使您的代码真正简洁。

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

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

?:为您提供了一种处理后备情况的方法,即使您有多层后备。如果是这样的话,你可以简单地用链条将猫王的运算符相乘,就像这样:

val l = listOf(1, 2, 3)


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

如果你用 If else 来表达同样的意思,那么就会有更多的代码难以阅读。

DR: 如果结果对象引用[第一个操作数]不是 null,则返回它。否则返回第二个操作数(可能是 null)的值。此外,如果返回 null,操作符可以引发异常。


猫王接线员是许多编程语言的一部分,例如 Kotlin,但也包括 Groovy 或 C # 。 我发现 维基百科的定义非常准确:

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

科特林的情况尤其如此:

有些计算机编程语言对这个操作符有不同的语义。与第一个操作数必须导致布尔值不同,它必须导致对象引用.如果结果对象引用不是 null,则返回它。否则返回第二个操作数(可能是 null)的值。如果第二个操作数为空,则该操作符也能够引发异常。

举个例子:

x ?: y // yields `x` if `x` is not null, `y` otherwise.
x ?: throw SomeException() // yields `x` if `x` is not null, throws SomeException otherwise

猫王接线员用问号表示,后面跟冒号: ?:,它可以与下面的语法一起使用:

first operand ?: second operand

它使您能够编写一个简明的代码,其工作原理如下:

如果 first operand 不是无效的,那么它将被返回。如果是 是无效的,则返回 second operand。这可以用来保证表达式不会返回 null 值,因为如果提供的值为 null,则将提供一个非空值。


例如(在科特林) :

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"

还要注意,如果左边是 无效,则计算右边的表达式 只有

在 Kotlin,你可以使用任何表达式作为 second operand,比如 throw Exception表达式

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

猫王的名字来自美国著名歌手 猫王。他的发型像一个问号

Elvis QuestionMark

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

简单地说,你有两只手。你想知道,你的左手现在能用吗?.如果左手不工作,则 return

Java 示例:

private int a;
if(a != null){
println("a is not null, Value is: "+a)
}
else{
println("a is null")
}

科特林的例子:

val a : Int = 5
val l : Int = if (a != null) a.length else "a is null"

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

也就是说。

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

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

Kotlin 的猫王操作员被用于零安全。

x = a ?: b

在上面的代码中,如果 a 不是 nullx将被赋予 a的值; 如果 anullb将被赋予 a的值。

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

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

不过还有一个小小的补充

X = A ?: B

如果 AB都评估为 null,那么 X仍然是 null

因此,如果您希望 X始终是 non-null,请确保 B始终是 non-null,或者如果 B是函数或表达式,则 B始终计算为 non-null

考虑下面的例子,

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
}

使用 猫王运算符,上面的代码可以写在一行中

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

除了已经满足的内容之外,还有一个好的模式,对我来说并不明显,但是很常见,例如,你正在编写一个长函数,但是如果某个内容是 无效,那么继续下去就没有意义了,你唯一能做的就是从函数返回。通常你会写信

something = expression
if (something == null) {
return
}

有了猫王,它变得更短更优雅:

something = expression ?: return