오늘은
Break, Retrun, Label에 관련한 공부를 하려고 합니다.
코틀린의 3개의 점프 표현식
return
: 가장 인접한 둘러싸인 함수 또는 익명 함수로부터 반환break
: 가장 인접한 둘러싸인 반복 종료continue
: 가장 인접한 둘러싸인 반복의 다음 단계 진행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도 같은 구조인지는 모르겠습니다 ㅠㅠㅠ
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
만을 출력한다.
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@label
이 continue
의 기능처럼 수행하는 것을 알 수가 있었다.
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 취급해 사용을 하였다.
이 형태는 람다 표현식 내에 함수이름을 라벨 이름으로 사용할 수 있다.
다른 프로젝트를 했을 때 이런 형태를 자주 쓰는 것 같다.
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@ 라벨 위치로 이동을 하기 때문에 반복이 중단되어 함수가 종료된다.
// 값을 리턴할 때 파서는 자격이 있는 리턴에 우선권을 부여함.
val num = run a@ {
// innerNum은 반환을 받지 못함
val innerNum = run {
return@a 1
}
println("innerNum : ${innerNum}")
}
println(num)
- 결과 -
1
위의 경우 2중첩이 된 형태인데
이때 원하는 label 위치로 return 값을 전달할 경우
label로 지정한 block이 우선권을 가지기 때문에
innerNum
은 반환이 안되는 결과를 확인 할 수가 있다.
또한 return이 되므로 출력 역시 안되는 것을 볼 수가 있다.