はじめに
KotlinのforEach文の中で、従来のcontinue
みたいにループ処理の中断をしたくて、次のように書きました。
val studentsScores = arrayOf(arrayOf(62, 89, 73), arrayOf(79, 100, 86), arrayOf(38, 68, 74))
studentsScores.forEach { scores ->
scores.forEach { score ->
if (score < 80) {
continue@forEach
}
print("合格!!(${score}点)")
}
}
すると、continue@forEach
のところでThe label '@forEach' does not denote a loop
とビルドエラーになりました。
continueの代わりにreturnを使う
少し調べて、continue@forEach
ではなくreturn@forEach
とすべきだとわかり、次のように直しました。
val studentsScores = arrayOf(arrayOf(62, 89, 73), arrayOf(79, 100, 86), arrayOf(38, 68, 74))
studentsScores.forEach { scores ->
scores.forEach { score ->
if (score < 80) {
return@forEach
}
print("合格!!(${score}点)")
}
}
しかし、今度はreturn@forEach
のところでthere is more than one label with such a name in this scope
と警告が出るようになりました。
どうやらforEachが二重になってるので、どっちに対するreturnなのか明言されてないよ、ということらしい。
ビルド自体は通って期待通りの結果を得られるので、そのままでも問題はないのですが、どうせなら警告も消したいですね。
同じ構文でネストしてる場合はラベルを使う
さらに少し調べて、Kotlinにはラベルという便利な機能があることを知り、再び以下のように直しました。
val studentsScores = arrayOf(arrayOf(62, 89, 73), arrayOf(79, 100, 86), arrayOf(38, 68, 74))
studentsScores.forEach { scores ->
scores.forEach scoreLoop@ { score ->
if (score < 80) {
return@scoreLoop
}
print("合格!!(${score}点)")
}
}
@scoreLoop
ラベルを付けたことにより、これは内側のforEach文のreturnだよ、と明言することができました。
警告が出なくなった上にコードも読みやすさも上がった気がして、スッキリしました。