해결된 질문
작성
·
152
·
수정됨
1
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
iterate(numbers) { num ->
if (num == 3) {
return@iterate
}
println(num)
}
}
fun iterate(numbers: List<Int>, exec: (Int) -> Unit) {
for (number in numbers) {
exec(number)
}
}
1
2
4
5
Process finished with exit code 0
람다식 내부에서 return
사용이 불가능하다고 하셨는데
위 처럼 @iterate
라벨로 명시적으로 선언하면 3만 빠진 수만 리턴하는 것을 볼 수 있었습니다.
위 방식으로는 non-local return 문제를 해결했다고 볼 수 없나요?
강의 정말 재밌게 듣고 있습니다! 감사합니다.
답변 1
1
안녕하세요 noose님!! ☺ 좋은 질문 감사드립니다~! 빠르게 답변드려보겠습니다! 🙇
맞습니다! 코틀린에 존재하는 라벨 기능을 사용하면 return@label 과 같이 특정 지점으로 return 시킬 수 있습니다!
아무래도 특정 지점으로 점프 시키는 기능이 goto와 유사한 면이 있어 권장되지는 않지만, 이런 기능을 사용하면 forEach + 람다 조합에서도 continue 혹은 break를 만들 수 있죠!
그렇다면 이것은 non-local return 문제를 해결한 것인가!!
결론부터 말씀드려보면 저는 non-local return이 어떤 문법적 이름이라고 생각합니다.
람다식 안에 return이 있고 해당 return이 람다식이 아닌 바깥의 함수를 return 시킨다면 그 return을 non-local return이라 부르기로 한 것이죠! 👍
아마 noose님께서 질문 주신 의도는 “라벨을 사용하면, 람다에서도 반환 시킬 수 있는데 이건 non-local return이 아닌거죠?”인 것 같아요 ☺
이에 대한 답변을 드려보면, 라벨을 사용한 return은 non-local return이 아니고 라벨을 기준으로 반환하기 때문에 non-local return처럼 동작하지 않습니다!
답변이 도움이 되었으면 좋겠습니다! 또 궁금한 점 있으시면 편하게 질문 남겨주세요~ 열심히 봐주셔서 감사합니다!! 🙇
상황에 따라 많이 다르겠지만, 우선 저는 label을 사용하는 것보다 단순한 Iterable을 사용할 것 같습니다! 말씀해주신 것처럼 라벨을 쓰는 경우는 거의 없고, 그나마 쓰고 싶은 마음이 생길 때라면 break 혹은 continue를 람다와 함께 쓰고 싶을 때 정도거든요!
다소 단편적이지만 위의 예시를 들어 보면, iterate
함수 자체를 굳이 분리하지 않고 main 함수에 for문을 사용해서 익숙한(?) return을 쓰는 쪽으로 코드를 바꿀 것 같습니다 🙂
val list = listOf(1, 2, 3, 4, 5)
for (num in list) {
if (num == 3) {
return
}
println(num)
}
간단히 요약드리면
우선은 최대한 라벨을 사용하지 않기 위해 노력한다.
정말 어쩔 수 없이 라벨을 써야하는 경우 (지금까지 저는 거의 없었습니다!!) 라벨을 사용한다.
로 되겠네요!! 👍 감사합니다!! 🙏
질문이 애매했는데 정말 잘 잡아주셨네요.
답변 감사합니다!
이런 상황이 많이 없을 것 같지만
혹시 태현님은 실무에서 어떤 방법을 주로 사용하시는지요?
라벨을 사용하지 않았으나 최근에 간단한 람다식을 사용할 때 사용해봤습니다.