Returns And Jumps

Panda·2022년 2월 14일
0

Kotlin

목록 보기
4/10

오늘은
Break, Retrun, Label에 관련한 공부를 하려고 합니다.

코틀린의 3개의 점프 표현식

  • return : 가장 인접한 둘러싸인 함수 또는 익명 함수로부터 반환
  • break : 가장 인접한 둘러싸인 반복 종료
  • continue : 가장 인접한 둘러싸인 반복의 다음 단계 진행

Break와 Label

Label 은 식별자로 @를 사용한다.
ex) abc@, fooBar@

loop@ for (i in 1..100) {
	println("i : ${i}")
    for(j in 1..100) {
    	println("j : ${j}")
    	// 라벨이 붙여진 break는 loop@가 표시된곳으로 이동후 break 실행함
    	if(j == 3)
    		break@loop
    }
}
println("벗어나기 완료!")

- 결과 -
i : 1
j : 1
j : 2
j : 3
벗어나기 완료!

break and label은
해당 label로 이동후 break를 수행을 하게 됩니다.

위의 결과를 확인하고 느낀점은
언어를 가장 처음에 배웠을 때 c언어를 배웠는데
그때 goto문을 배운 느낌이 강하게 느꼈습니다.

근데 그때 배웠던 내용은 최대한 goto 문을 자제하라고 배우긴했는데
시대의 흐름에 따라 goto도 적절히 사용을 하면 좋다고 하더라고요.

내부적인 파이프라인 흐름떄문에 그런걸로 알고있는데
코틀린 label도 같은 구조인지는 모르겠습니다 ㅠㅠㅠ

Return 과 Label

1.

fun foo() {
	listOf(1, 2, 3, 4, 5).forEach {
    	if(it == 3)
        	return
        println(it)
    }
    println("done with explicit label")
}

fun main(args : Array<String>) {
	foo()
}

- 결과 -
1
2

일반적으로 우리가 흔히 쓰는 return 문이다.
당연히 3일때 return이 되어 함수가 종료되기 때문에
1, 2 만을 출력한다.

2.

fun foo() {
	listOf(1, 2, 3, 4, 5).forEach lit@{
    	if(it == 3)
        	return@lit
        println(it)
    }
    println("done with explicit label")
}

- 결과 -
1
2
4
5
done with explicit label

자 이제 label을 활용해 보자면
3일때 return@lit 을 수행을 하게 되는데
함수가 종료되는 것이 아닌 continue 기능을 수행하는 것을 알 수가 있다.
이렇게 반복구문에서는 return@labelcontinue의 기능처럼 수행하는 것을 알 수가 있었다.

3.

fun foo() {
	// 람다 표현식 내에 함수를 라벨 이름으로 사용할 수있다!!!!!!!!
    listOf(1, 2, 3, 4, 5).forEach {
        if(it == 3)
            return@forEach
        println(it)
    }
    println("done with explicit label")
}

- 결과 -
1
2
4
5
done with explicit label

2번과 거의 유사한 예제인데 다만
label을 직접 정의한 것이 아니라
함수 이름을 label 취급해 사용을 하였다.
이 형태는 람다 표현식 내에 함수이름을 라벨 이름으로 사용할 수 있다.

다른 프로젝트를 했을 때 이런 형태를 자주 쓰는 것 같다.

4.

fun foo() {
	run loop@{
    	listOf(1, 2, 3, 4, 5).forEach {
        	if (it == 3)
                return@loop // 람다 표현식을 지나 run 위치에서 리턴
            println(it)
        }
    }
    println("done with nexted loop")
}

- 결과 -
1
2
done with nexted loop

2중으로 감싸져있는 모습을 볼 수가 있는데
가장 바깥부분인 run에 label을 지정을 하여서

return@loop 를 해주는 모습이다.

이때는 loop@ 라벨 위치로 이동을 하기 때문에 반복이 중단되어 함수가 종료된다.

Priority

// 값을 리턴할 때 파서는 자격이 있는 리턴에 우선권을 부여함.
val num = run a@ {
	// innerNum은 반환을 받지 못함
	val innerNum = run {
		return@a 1
	}
	println("innerNum : ${innerNum}")
}

println(num)

- 결과 -
1

위의 경우 2중첩이 된 형태인데
이때 원하는 label 위치로 return 값을 전달할 경우
label로 지정한 block이 우선권을 가지기 때문에
innerNum은 반환이 안되는 결과를 확인 할 수가 있다.
또한 return이 되므로 출력 역시 안되는 것을 볼 수가 있다.

profile
실력있는 개발자가 되보자!

0개의 댓글

관련 채용 정보