코틀린은 제어를 넘기는 세가지 구조적인 return과 jump 표현식이 있다. 이는 더 큰 표현식의 일부로 사용이 가능하다. Type은 Nothing 타입이다.
- return : return은 가장 가까운 블록의 함수 또는 익명 함수를 종료하고 반환된다.
- break : 가장 가까운 반복 루프를 중단시킨다.
- continue : 가장 가까운 반복 루프를 다음 반복으로 진행시킨다.
val s = person.name ?: return
Break and continue lables
코틀린의 모든 표현식은 레이블로 표현될 수 있다. break와 continue를 레이블과 함께 사용할 수 있다. 레이블과 함께 사용하는 경우 해당 레이블이 붙은 루프의 반복을 제어할 수 있다. 레이블로 규정된 Break은 해당 레이블로 표시된 바로 뒤의 실행 지점으로 점프 한다. Continue는 해당 루프의 다음 반복으로 진행된다.
loop@ for (i in 1..100) {
for (j in 1..100) {
if (...) break@loop
}
}
🐯 레이블(label)?
@키워드가 뒤에 오는 식별자 형식으로 레이블을 지정하려는 표현식의 앞에 추가하면 된다.
Return to labels
코틀린에서 함수는 함수 리터럴, 로컬 함수 및 객체 표현식을 사용해서 중첩될 수 있다. 한정된 return을 사용하면 외부 함수에서 반환할 수 있다. 가장 중요한 사용 사례는 람다식에서 반환하는 것 이다. 이 경우에 람다식 내의 return 표현식은 가장 가까운 둘러싸는 함수에서 반환된다.
fun foo() {
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return // non-local return directly to the caller of foo()
print(it)
}
println("this point is unreachable")
}
위와 같은 비지역적인 반환은 인라인 함수에 전달된 람다식에 대해서만 지원한다. → 람다식내에서 반환하려면 레이블을 지정하고 반환을 한정해야 한다.
fun foo() {
listOf(1, 2, 3, 4, 5).forEach lit@{
if (it == 3) return@lit // local return to the caller of the lambda - the forEach loop
print(it)
}
print(" done with explicit label")
}
/* 결과
* 1245 done with explicit label
*/
람다식이 전달되는 함수와 이름이 같은 암묵적 레이블을 사용하여 같은 코드를 더 편리하게 사용할 수 있다.
fun foo() {
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@forEach // local return to the caller of the lambda - the forEach loop
print(it)
}
print(" done with implicit label")
}
/* 결과
* 1245 done with implicit label
*/
람다식을 익명 함수로 바꿀 수 있다. 익명함수의 return 문은 레이블 없이 익명 함수 자체에서 반환된다. 지역적 반환을 사용하는 것은 일반 루프에서 continue를 사용하는 것과 유사한 효과를 낼 수 있다.
fun foo() {
listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
if (value == 3) return // local return to the caller of the anonymous function - the forEach loop
print(value)
})
print(" done with anonymous function")
}
/* 결과
* 1245 done with anonymous function
*/
break에 대해 직접적으로 같은 것은 없지만, 다른 중첩 람다를 추가하고 이로부터 비로컬적으로 반환하여 시뮬레이션 할 수 있다.
fun foo() {
run loop@{
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@loop // non-local return from the lambda passed to run
print(it)
}
}
print(" done with nested loop")
}
/* 결과
* 12 done with nested loop
*/
값을 반환할 때, parser는 정규식 반환에 우선권을 부여한다.
return@a 1
위 예시의 경우 레이블이 있는 표현식 @a 1을 반환한다는게 아니라 레이블 @a 에서 1을 반환한다는 것이다.