我要干嘛
先说结论
kotlin的elvis并没有简化很多,反而降低了代码的可读性,让人难以理解。还是乖乖用Java那一套吧。
看看代码
在Java中我们常见的判空的写法是这样的:
val s = StringProducer.produce()
if (s != null) {
println(s)
} else {
println("StringProducer.produce() return empty")
}
在Kotlin中有一种写法,叫做elvis操作符。见官网:https://kotlinlang.org/docs/null-safety.html#elvis-operator
我们这里尝试用elvis来改写:
StringProducer.produce()?.let {
println(it)
} ?: run {
println("StringProducer.produce() return empty")
}
这里在elvis表达式,即?:
的右侧用了run{}
这个领域函数。
实际上?:
的右侧是需要跟一个表达式的,但是我们想要嵌入的是一个代码块,因此我们可以嵌入一个含有代码块的表达式。
注意,这里run{}
实际上是没有返回值的,因此他返回的其实是空,但是没关系,因为我们这条调用链本身没有接收者来接住这个值。
为什么选用了run函数而不用其他的领域函数?因为run函数是唯一一个不需要上下文的函数,他可以不需要参数,并且不是拓展函数,因此可以直接调用。(这一点在官网领域函数中有说明的)
看看效果
从代码上看出来,只少了一行的调用。
但是我们的代价是什么?
- 加大复杂度【重点】:在这里引入了两个领域函数的调用,加大了复杂性和可读性。
- 降低性能:虽说这两个领域函数都是带有
inline
内联关键字防止创建新的局部匿名对象,但是依然有领域函数内部的调用,增加了栈深度。
因此结论是:
kotlin的elvis并没有简化很多,反而降低了代码的可读性,让人难以理解。还是乖乖用Java那一套吧。