returnとジャンプ
Kotlinには3つの構造的ジャンプ演算子があります。
- return はデフォルトではそれを包む最も近い関数または無名関数から抜け出します。
- break はそれを包む最も近いループを終わらせます。
- continue はそれを包む最も近いループを、次のステップに進めます。
これらはすべて、より大きな式の一部として使う事が出来ます:
val s = person.name ?: return
これらの式の型はNothing型です。
breakとcontinueのラベル
Kotlinにおける任意の式を labelでマークすることができます。ラベルは、識別子の後ろに@
記号が続く形式です。
例えばabc@
、fooBar@
など。
式にラベルを付けるには、式の前にラベルを置きましょう:
loop@ for (i in 1..100) {
// ...
}
さあ、これで私たちは break や continue をラベル付きで出来るようになりました:
loop@ for (i in 1..100) {
for (j in 1..100) {
if (...) break@loop
}
}
ラベル付き break はそのラベルが付いたループのすぐ後の実行ポイントへジャンプします。 continue はそのループの次の繰り返し実行(イテレーション)まで進みます。
ラベルにreturnする
Kotlinでは、関数リテラル、ローカル変数、object式を使用すると、関数を入れ子にすることができます。
ラベル付きの returnを使うと、外側の関数からreturnすることができます。
最も重要なユースケースは、ラムダ式からのreturnです。
以下のように書くと、return
式は最も近いそれを包んでいる関数、つまりfoo
からreturnする事を思い出してください:
このようなnon-local なreturnはインライン関数に渡されたラムダ式でのみサポートされていることに注意してください。 もしラムダ式からだけ復帰する必要がある場合は、そのラムダ式にラベルを付け、 return をラベルで修飾する必要があります:
上の例は、(二つ前の例と異なり)ラムダ式からのみ復帰しています。
多くの場合、暗黙のラベル(implicit labels)を使用する方が便利です。 そのようなラベルは、ラムダが渡された関数と同じ名前を持っています。
代わりの手法として、ラムダ式の代わりに無名関数を使うという方法もあります。 無名関数内の return 文は、その無名関数自体から復帰します。
上記の3つのlocal returnの例は、通常のループのcontinue
と似ているということに注目してください。
break
相当のものは直接は存在しませんが、
外側にlambdaを足してそこからnon-localにreturnすれば同じような機能を実現出来ます:
値を返すとき、パーサはラベル付けreturnの方を優先します。すなわち、
return@a 1
上記は「 @a
ラベルからのreturn 1
」を意味し、「 ラベルが付いた式(@a 1)
をreturn」ではありません。