조용한 담장

코틀린(Kotlin) : 리턴 과 점프 (Returns and Jumps) 본문

kotlin

코틀린(Kotlin) : 리턴 과 점프 (Returns and Jumps)

iosroid 2019. 12. 31. 16:14

코틀린(kotlin)의 returns and jumps 를 보자.

원문 https://kotlinlang.org/docs/reference/returns.html 을 보며 정리.

 

kotlin structural jump expressions : returnbreakcontinue

위 세계의 표현은 Nothing type 이다.

val s = person.name ?: return

Break and Continue Labels

expression 은 label 로 표시될 수 있으며 식별자(identifier) @ 뒤에 붙는다.

예) abc@, foobar@

참조 : grammar for label

아래와 같이 break 나 continue 가 jump 할 대상의 label 을 expression 앞에 붙여 표시한다.

loop@ for (i in 1..100) {
    for (j in 1..100) {
        if (...) break@loop
    }
}

break 는 loop@ label 표시가 된 첫번째 for 의 바로 다음 수행 코드로 jump 하게 되어 전체 루프가 종료되게 된다.

continue 인 경우에는 다음 반복문 동작으로 건너뛴다.

Return at Labels

아래와 같은 코드의 return 은 forEach() 내에서 수행되지만 foo() 함수를 종료시킨다.

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 에 label 을 적용하면(qualified return) 전체 종료를 하지 않게 할 수 있다.

fun foo() {
    listOf(1, 2, 3, 4, 5).forEach lit@{
        if (it == 3) return@lit // local return to the caller of the lambda, i.e. the forEach loop
        print(it)
    }
    print(" done with explicit label")
}

위 예제와 같이 중첩 함수 같은 경우에 return 을 원하는 범위 내에서 동작하게 할 수 있으며 주로 lambda 에서 유용하게 쓰일 수 있다.

implicit labels 은 아래의 forEach 와 같이 람다의 함수이름과 동일하게 생성되어 사용할 수 있다.

fun foo() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return@forEach // local return to the caller of the lambda, i.e. the forEach loop
        print(it)
    }
    print(" done with implicit label")
}

label 을 사용하지 않고 anonymous function 을 사용하면 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 fun, i.e. the forEach loop
        print(value)
    })
    print(" done with anonymous function")
}

값을 리턴할 때, 파서는 qualified return 의 레퍼런스를 전달한다.

return@a 1

위 코드는 label @a 에 1을 리턴한다는 의미이며, (@a 1) 표현식을 리턴한다는 뜻이 아니다.

루프에서 continue 를 쓰는 동작을 아래처럼 qualified return 을 쓰는 방법도 있다.

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")
}

 

 

 

 

 

 

Comments