Skip to main content

흐름의 중단과 반환

흐름 제어문

  • return: 함수에서 결과값을 반환하거나 지정된 라벨로 이동한다.
  • break: for문이나 while문의 조건식에 상관없이 반복문을 끝낸다.
  • continue: for문이나 while문의 본문을 보두 수행하지 않고 다시 조건식으로 넘어간다.

return

람다식에서 return 사용

inline 키워드는 성능 최적화를 위해 특정 함수가 호출될 때 함수 호출 자체를 없애고, 함수의 본문을 호출 지점에 직접 삽입하는 것을 의미합니다. 이는 주로 람다 함수를 사용하는 고차 함수에서 사용됩니다. inline 키워드를 사용하면 함수 호출에 대한 오버헤드를 줄이고, 성능을 향상시킬 수 있습니다. 그러나 inline은 주로 특정 상황에서 유용하며, 모든 함수에 적용하는 것은 권장되지 않습니다.

인라인(inline)으로 선언되지 않은 람다식에서는 return을 그냥 사용할 수 없습니다. return, @label과 같이 라벨(label) 표기와 함께 사용해야 합니다.

fun main() {
retFunc() // start of retFunc
}

inline fun inlineLambda(
a: Int,
b: Int,
c: (Int, Int) -> Unit,
): Unit = c(a, b)

fun retFunc() {
println("start of retFunc")
inlineLambda(7, 11) { a, b ->
val result = a + b
if (result > 10) { // 해당 함수를 빠져나감
return
}
println("result: $result")
}
println("end of retFunc")
}

람다식에서 라벨과 함께 return 사용

  • 인라인 여부 무관
fun main() {
retFunc() // start of retFunc
}

fun main() {
retFunc()
}

inline fun inlineLambda(
a: Int,
b: Int,
c: (Int, Int) -> Unit,
): Unit = c(a, b)

fun retFunc() {
println("start of retFunc")
inlineLambda(7, 11) lit@{ a, b ->
val result = a + b
if (result > 10) { // 해당 함수를 빠져나감
return@lit // 라벨을 사용한 블록의 끝부분으로 반환
}
println("result: $result")
}
println("end of retFunc")
}

암묵적 라벨

람다식 표현식 블록에 직접 라벨을 쓰는 것이 아닌 람다식 명칭을 그대로 라벨처럼 사용할 수 있는데 이를 암묵적 라벨이라고 부릅니다.

fun main() {
retFunc()
}

inline fun inlineLambda(
a: Int,
b: Int,
c: (Int, Int) -> Unit,
): Unit = c(a, b)

fun retFunc() {
println("start of retFunc")
inlineLambda(7, 11) { a, b ->
val result = a + b
if (result > 10) { // 해당 함수를 빠져나감
return@inlineLambda // 암묵적 라벨(inlineLambda, retFunc)
}
println("result: $result")
}
println("end of retFunc")
}

break문, continue문

break와 continue에 라벨 함께 사용하기

fun main() {
/**
* 출력
* before outer loop
* (1, 1)
* (1, 2)
* after inner loop
* (2, 1)
* (2, 2)
* after inner loop
* (3, 1)
* (3, 2)
* after inner loop
* (4, 1)
* (4, 2)
* after inner loop
* (5, 1)
* (5, 2)
* after inner loop
* after outer loop
*/
labelBreak()
}

fun labelBreak() {
println("before outer loop")
outer@ for (i in 1..5) {
inner@ for (j in 1..5) {
if (j == 3) {
break@inner
}
println("($i, $j)")
}
println("after inner loop")
}
println("after outer loop")
}
fun main() {
/**
* 출력
* before outer loop
* (1, 1)
* (1, 2)
* after outer loop
*/
labelBreak()
}

fun labelBreak() {
println("before outer loop")
outer@ for (i in 1..5) {
inner@ for (j in 1..5) {
if (j == 3) {
break@outer
}
println("($i, $j)")
}
println("after inner loop")
}
println("after outer loop")
}

fun main() {
/**
* 출력
* before outer loop
* (1, 1)
* (1, 2)
* (2, 1)
* (2, 2)
* (3, 1)
* (3, 2)
* (4, 1)
* (4, 2)
* (5, 1)
* (5, 2)
* after outer loop
*/
labelBreak()
}

fun labelBreak() {
println("before outer loop")
outer@ for (i in 1..5) {
inner@ for (j in 1..5) {
if (j == 3) {
continue@outer
}
println("($i, $j)")
}
println("after inner loop")
}
println("after outer loop")
}