Is `a?.let{} ?: run{}` idiomatic in Kotlin?

梦想的初衷 提交于 2019-12-03 14:06:47

In that case, you'll need a?.let{} ?: run{} instead of if{} else {}

No, you can omit the run part of run { statement } and use a?.let{} ?: statement.

Should I avoid it in most cases?

You should use it when you need it. E.g. when you want to run multiple statements in that scenario. It is pointed out that that is a rare scenario. Often you will see just a single statement on the right hand side of an elvis operator.
And of course don't use it when you don't need it. Keep the code simple.

It's dangerous to conflate foo?.let { bar(it) } ?: baz() with if (foo != null) bar(foo) else baz().

Say you have a function: fun computeElements(): List<Int>? = emptyList()

Consider this code:

val maxElement = computeElements()?.let { it.max() } ?: return
println("Max element was $maxElement")

Compared to:

val list: List<Int>? = computeElements()
val maxElement = if (list != null) list.max() else return
println("Max element was $maxElement")

You may think these are two equivalent forms. However, if you run both, you'll see that the former does not print anything to stdout!

This is because it.max() returns null for an empty list (because there is no max element), which causes the right-hand side of the Elvis expression to be evaluated, and so the function returns early.

In short, ?.let { ... } ?: ... allows both branches of the "if-else" to be evaluated, which is dangerous. Aside from this form not being readable (if-else is universally understood, while let-run is not), subtle bugs can occur.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!