🏄
Kotlinのwhen式で早期リターンしたい
はじめに
when式のブロック内の処理で、早期リターンしたいと思うことがありました。
return@when emptyList()
みたいに書けると思いきや、文法エラーで怒られました。。
TL;DL
早期リターンしたいブロックの返り値をletにすることで擬似的に早期リターンできました。
val foo = listOf(1, 2)
val condition1 = true
val condition2 = true
val bar = when (foo.size) {
// foo.sizeが1の時の返り値はlet
1 -> let {
if (condition1 && condition2) {
// 厳密にはletに対して早期リターン
// letの値がそのままwhenの返り値になるため、擬似的に早期リターン成功!!
return@let 1
}
2
}
else -> {
3
}
}
println(bar)
関数化しろよというツッコミはご容赦ください。
多くのシーンでは関数化すべきだと思います🙁
関数で対応する場合(推奨)
val bar = when (foo.size) {
1 -> {
returnWhen1(condition1, condition2)
}
else -> {
3
}
}
println(bar)
fun returnWhen1(condition1: Boolean, condition2: Boolean): Int {
if (condition1 && condition2) {
return 1
}
return 2
}
ちなみにうまくいかなかった対応
labelで名前をつけることでジャンプすることができます。
これを使用しどうにかできないかなと思いましたが、うまくいきませんでした。
when式自体にlabelをつけてみた
val bar = whenLabel@ when (foo.size) {
1 -> {
if (condition1 && condition2) {
return@whenLabel 1
}
2
}
}
when式の対象ブロックにlabelをつけてみた
これならできるのではと期待はありました。
letに近い対応で、labelがあればreturnできるようになる…とは行きませんでした🥲
val bar = when (foo.size) {
1 -> whenLabel@ {
if (condition1 && condition2) {
return@whenLabel 1
}
2
}
}
まとめ
when式では早期リターンできませんでした。
ちなみにif式も同様で、同じ方法で対応できました。
whenやifは式で、letやforEachは関数だからできないのかと思いましたが、for文はlabelに対応しているんですよね🤔
言語上の成約があるのか、関数化しろという思想なのか。
大人しく関数化しておきましょう。。
Discussion