リターンとジャンプ
Kotlinには、3つの構造的なジャンプ式があります。
return
は、デフォルトで、最も内側の関数または無名関数から戻ります。break
は、最も内側のループを終了させます。continue
は、最も内側のループの次のステップに進みます。
これらの式はすべて、より大きな式の一部として使用できます。
val s = person.name ?: return
これらの式の型は、Nothing型です。
Breakとcontinueのラベル
Kotlinの任意の式には、_ラベル_を付けることができます。
ラベルの形式は、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
は、そのループの次のイテレーションに進みます。
場合によっては、ラベルを明示的に定義せずに、非ローカルに break
と continue
を適用できます。
このような非ローカルな使用は、囲みインライン関数で使用されるラムダ式で有効です。
ラベルへのReturn
Kotlinでは、関数リテラル、ローカル関数、およびオブジェクト式を使用して関数をネストできます。
修飾された return
を使用すると、外側の関数から戻ることができます。
最も重要なユースケースは、ラムダ式から戻ることです。ラムダ式から戻るには、
ラベルを付けて return
を修飾します。
fun foo() {
listOf(1, 2, 3, 4, 5).forEach lit@{
if (it == 3) return@lit // ラムダの呼び出し元(forEachループ)へのローカルリターン
print(it)
}
print(" done with explicit label")
}
fun main() {
foo()
}
これで、ラムダ式からのみ戻ります。多くの場合、_暗黙的なラベル_を使用する方が便利です。このようなラベルは、 ラムダが渡される関数と同じ名前を持つためです。
fun foo() {
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@forEach // ラムダの呼び出し元(forEachループ)へのローカルリターン
print(it)
}
print(" done with implicit label")
}
fun main() {
foo()
}
または、ラムダ式を無名関数に置き換えることもできます。
無名関数の return
ステートメントは、無名関数自体から戻ります。
fun foo() {
listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
if (value == 3) return // 無名関数の呼び出し元(forEachループ)へのローカルリターン
print(value)
})
print(" done with anonymous function")
}
fun main() {
foo()
}
前の3つの例でのローカルリターンの使用は、通常のループでの continue
の使用と似ていることに注意してください。
break
に直接相当するものはありませんが、別のネストされたラムダを追加し、そこから非ローカルに戻ることによってシミュレートできます。
fun foo() {
run loop@{
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@loop // runに渡されたラムダからの非ローカルリターン
print(it)
}
}
print(" done with nested loop")
}
fun main() {
foo()
}
値を返す場合、パーサーは修飾されたreturnを優先します。
return@a 1
これは、「ラベル @a
で 1
を返す」という意味であり、「ラベル付きの式 (@a 1)
を返す」という意味ではありません。
場合によっては、ラベルを使用せずにラムダ式から戻ることができます。このような 非ローカル リターンは、 ラムダ内にありますが、囲みインライン関数を終了します。