본문 바로가기

Kotlin

Kotlin - Returns and jumps

아래 3키워드 들은 Kotlin에서 코드를 jump 하려고 할때 사용되는 표현식 들이다.

  • return
    return 이 포함된 가장 가까운 함수의 결과값을 반환한다.
  • break
    break 가 포함된 가장 가까운 반복문(loop) 가 종료 된다.
  • continue
    continue 가 포함된 가장 가까운 반복문의 다음 스텝을 진행한다.

위 키워드들은 모두 표현식이기 때문에 다른 표현식의 일부로 작성 될 수도 있다. (Nothing 타입)

// 표현식 이기 때문에 이런 표현이 가능하다
val s = person.name ?: return

 

Break and continue labels

Kotlin 은 표현식에 label을 붙이는 것이 가능하다. Label을 붙이고 싶은 표현식 앞에 "{label명}@" 형태의 label 을 붙인다.

label을 붙이고 나면 break 나 continue 식의 범위를 지정할 수 있다.

for (i in 1..3) {
    for (j in 100..103) {
        if (i == 2) {
            break // 현재 가장 가까운 반복문인 for (j..) 에 break 가 걸린다.
        }
        println("i: $i, j: $j")
    }
}

// i: 1, j: 103
// i: 3, j: 100
// i: 3, j: 101
// i: 3, j: 102
// i: 3, j: 103


iLoop@ for (i in 1..3) {
    jLoop@ for (j in 100..103) {
        if (i == 2) {
            break@iLoop // iLoop 에 break 가 걸린다.
        }
        println("i: $i, j: $j")
    }
}

// i: 1, j: 100
// i: 1, j: 101
// i: 1, j: 102
// i: 1, j: 103

for (i in 1..3) {
    for (j in 100..103) {
        if (j == 101) {
            continue // 현재 가장 가까운 반복문인 for (j..) 에 continue 가 걸린다.
        }
        println("i: $i, j: $j")
    }
}
// i: 1, j: 100
// i: 1, j: 102
// i: 1, j: 103
// i: 2, j: 100
// i: 2, j: 102
// i: 2, j: 103
// i: 3, j: 100
// i: 3, j: 102
// i: 3, j: 103


iLoop@ for (i in 1..3) {
    jLoop@ for (j in 100..103) {
        if (j == 101) {
            continue@iLoop // iLoop 에 continue 가 걸린다.
        }
        println("i: $i, j: $j")
    }
}
// i: 1, j: 100
// i: 2, j: 100
// i: 3, j: 100

 

Return to labels

Kotlin 은 function 안에 local function 이나 funtion 리터럴을 작성 할 수 있다. 그래서 return 을 사용했을때 외부 function 에 대한 return이 발생하기도 하고 내부 function 의 return이 발생하기도 한다.

람다의 경우 기본적으로 non-local return(외부 함수return) 으로 동작한다. 따라서 local-return (람다 return)을 하고 싶다면 label을 활요하거나 암시적 label을 활용한다. 

암시적 label (implicit label)이란? 람다를 인자로 받는 함수명과 동일한 이름의 label이 자동으로 생기는데 이것을 말한다.

fun foo1() {
    // 람다 식 에서는 non-local return으로 동작한다.
    listOf(1, 2, 3, 4).forEach {
        if (it == 3) return // foo1() 함수를 리턴한다. (non-local return)
        print(it)
    }
    println("this point is unreachable") // 여기까지 못옴
}

fun foo2() {
    // 람다 식 에서는 local return으로 동작하기 위해서는 label을 붙여야 한다.
    listOf(1, 2, 3, 4).forEach lit@{
        if (it == 3) return@lit // 람다 식을 리턴한다. (local return)
        print(it)
    }
    println("done with explicit label")
}

fun foo3() {
    // 암시적 label(implicit labels)을 사용할 수도 있다.
    listOf(1, 2, 3, 4).forEach{
        if (it == 3) return@forEach // 람다 식을 리턴한다. (local return)
        print(it)
    }
    println("done with implicit label")
}

람다 대신 익명 함수를 사용할 수도 있는데, 익명 함수 내부에서의 return 은 local return 으로 동작하여 익명함수를 리턴한다.

fun foo4() {
    println("foo4 ====================")
    listOf(1, 2, 3, 4).forEach(fun (it: Int){
        if (it == 3) return // 익명 함수를 리턴한다. (local return)
        print(it)
    })
    println(" done with anonymous function")
}
반응형

'Kotlin' 카테고리의 다른 글

Kotlin - Packages and imports  (0) 2024.01.13
Kotlin - Exceptions  (0) 2024.01.12
Kotlin - 반복문(for, while)  (0) 2024.01.10
Kotlin - 조건문  (2) 2024.01.07
Kotlin - 타입체크와 형 변환  (0) 2024.01.06