我要干嘛

优化java对参数的空和非空的判断的写法。

先说结论

kotlin的elvis并没有简化很多,反而降低了代码的可读性,让人难以理解。还是乖乖用Java那一套吧。

看看代码

在Java中我们常见的判空的写法是这样的:

  1. val s = StringProducer.produce()
  2. if (s != null) {
  3. println(s)
  4. } else {
  5. println("StringProducer.produce() return empty")
  6. }

在Kotlin中有一种写法,叫做elvis操作符。见官网:https://kotlinlang.org/docs/null-safety.html#elvis-operator
我们这里尝试用elvis来改写:

  1. StringProducer.produce()?.let {
  2. println(it)
  3. } ?: run {
  4. println("StringProducer.produce() return empty")
  5. }

这里在elvis表达式,即?:的右侧用了run{}这个领域函数
实际上?:的右侧是需要跟一个表达式的,但是我们想要嵌入的是一个代码块,因此我们可以嵌入一个含有代码块的表达式。

注意,这里run{}实际上是没有返回值的,因此他返回的其实是空,但是没关系,因为我们这条调用链本身没有接收者来接住这个值。

为什么选用了run函数而不用其他的领域函数?因为run函数是唯一一个不需要上下文的函数,他可以不需要参数,并且不是拓展函数,因此可以直接调用。(这一点在官网领域函数中有说明的)

看看效果

从代码上看出来,只少了一行的调用。
但是我们的代价是什么?

  1. 加大复杂度【重点】:在这里引入了两个领域函数的调用,加大了复杂性和可读性。
  2. 降低性能:虽说这两个领域函数都是带有inline内联关键字防止创建新的局部匿名对象,但是依然有领域函数内部的调用,增加了栈深度。

因此结论是:
kotlin的elvis并没有简化很多,反而降低了代码的可读性,让人难以理解。还是乖乖用Java那一套吧。