Kotlin의 Return 과 점프 표현식
Kotlin에서는 프로그램의 흐름을 제어하기 위한 다양한 구조적 점프 표현식을 제공합니다. 이 가이드에서는 return
, break
, continue
의 사용법과 레이블을 활용한 고급 기법을 살펴보겠습니다.
기본 점프 표현식 (Basic Jump Expressions)
Kotlin은 세 가지 기본적인 구조적 점프 표현식을 제공합니다:
return
: 기본적으로 가장 가까운 enclosing 함수나 익명 함수에서 반환합니다.break
: 가장 가까운 enclosing 루프를 종료합니다.continue
: 가장 가까운 enclosing 루프의 다음 단계로 진행합니다.
이 표현식들은 더 큰 표현식의 일부로 사용될 수 있습니다:
val s = person.name ?: return
이 표현식들의 타입은 Nothing
타입입니다. 이는 이 표현식들이 "정상적인" 실행 흐름을 중단한다는 것을 의미합니다.
Break와 Continue 레이블 (Break and continue labels)
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
는 해당 루프의 다음 반복으로 진행합니다.
이 기능은 중첩된 루프에서 특정 루프를 빠져나가거나 특정 루프의 다음 반복으로 넘어가야 할 때 매우 유용합니다.
레이블을 사용한 Return (Return to labels)
Kotlin에서는 함수 리터럴, 로컬 함수, 객체 표현식을 사용하여 함수를 중첩할 수 있습니다. 한정된 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")
}
이 경우, return
표현식은 가장 가까운 enclosing 함수인 foo
에서 반환합니다. 이러한 non-local 반환은 인라인 함수에 전달된 람다 표현식에서만 지원됩니다.
람다 표현식에서 반환하려면 레이블을 붙이고 return
을 한정해야 합니다:
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")
}
이 경우, return@lit
은 람다 표현식에서만 반환합니다.
더 편리한 방법은 암시적 레이블을 사용하는 것입니다. 암시적 레이블은 람다가 전달되는 함수와 같은 이름을 가집니다:
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")
}
또는 람다 표현식을 익명 함수로 대체할 수 있습니다. 익명 함수 내의 return
문은 익명 함수 자체에서 반환합니다:
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")
}
이전 세 예제에서 로컬 반환의 사용은 일반 루프에서 continue
를 사용하는 것과 유사합니다.
break
에 대한 직접적인 동등한 표현은 없지만, 다른 중첩 람다를 추가하고 그로부터 non-locally 반환함으로써 시뮬레이션할 수 있습니다:
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")
}
값을 반환할 때, 파서는 한정된 반환에 우선순위를 줍니다:
return@a 1
이는 "labeled expression (@a 1)
를 반환"이 아니라 "레이블 @a
에서 1
을 반환"을 의미합니다.
Kotlin의 return 과 점프 표현식은 프로그램의 흐름을 세밀하게 제어할 수 있게 해줍니다. 특히 중첩된 루프나 람다 표현식에서 이러한 기능들은 매우 강력합니다. 하지만 과도한 사용은 코드의 가독성을 해칠 수 있으므로, 적절히 사용하는 것이 중요합니다.
이러한 기능들을 잘 이해하고 활용하면, 더 효율적이고 표현력 있는 Kotlin 코드를 작성할 수 있습니다. 특히 복잡한 로직을 가진 함수나 고차 함수를 다룰 때 이러한 기능들이 큰 도움이 될 것입니다.
Kotlin, 반환문, 점프표현식, 레이블, 람다표현식, 익명함수, 제어흐름, KotlinProgramming, 코틀린문법, 프로그래밍팁, 코드최적화, 함수형프로그래밍, 안드로이드개발, 백엔드개발, KotlinCoroutines
'개발&프로그래밍' 카테고리의 다른 글
[kotlin] 클래스 (0) | 2024.08.12 |
---|---|
[kotlin] Exceptions (0) | 2024.08.12 |
[Kotlin] 조건문과 반복문 (0) | 2024.08.11 |
[kotlin] 타입 체크와 캐스팅 (0) | 2024.08.11 |
[Kotlin] 숫자 타입과 연산 가이드 (4) | 2024.08.10 |
댓글