6.2.4 Elvis运算符

如果目标为null,安全调用运算符返回null。但是,如果我们想返回一个非空的内容呢?让我们对nickName()函数做进一步的改进,以便在调用方传入null时返回"Joker"。为此,我们可以将返回类型改为限制性更强的String,而不是String?。这里是所做的修改,但是在我们重构以恢复优雅之前,它会再次变得有点难看。

让我们快速看一下代码的输出:

函数现在接受String?允许null参数,但返回类型为String。如果名字不是"William",则使用reversed()将给定参数中的值颠倒,并将其转换为大写,就像之前一样。但是,在这个版本中,我们将连续两次使用安全调用的结果存储到一个名为result的临时变量中。然后执行null检查,如果结果为null,则返回"Joker",否则返回值。这些null检查就像是一部恐怖电影里的恶棍——它们总是不断出现。

我们既有好消息也有坏消息。在null检查后返回值不需要任何仪式。我们最终可以在else后面返回result,即使result的类型是String?,函数的返回类型是String。通常,我们不能在期望返回String的地方返回String?的实例。但是Kotlin知道我们已经用null检查付出了代价,所以不会再在这里给我们找麻烦了。坏消息是:我们写了两行代码并创建了一个临时变量。要是能减少混乱就好了,Elvis运算符——?:——来救援了。

如果表达式的结果不为null,Elvis运算符将返回左侧表达式的结果,否则它将计算并返回右侧表达式的结果。Elvis运算符会短路求值——也就是说,如果右侧不使用,它不会计算右侧的值。

在前面的代码中,让我们替换冗长的部分:

它变得像这样优雅:

Elvis运算符非常酷,就像同名歌手Presley先生一样。在扭曲的想象中,你可以看到眼睛:上方的发型?在情感符号?:里,这就是这个运算符的名字。

安全调用运算符和Elvis运算符是你的朋友,但有时你会有离开它们的冲动,用!!运算符使其更加简洁,但这可能不是一个好主意,正如接下来将看到的。