루프를 filter와 같이 람다를 호출하는 함수로 바꾸고, 인자로 전달하는 람다 안에서 return을 사용하면 어떤 일이 벌어질까?
8.3.1 람다 안의 return문: 람다를 둘러싼 함수로부터 반환
다음 코드의 실행 결과를 보면 이름이 Alice인 경우에 lookForAlice 함수로부터 반환된다는 사실을 분명히 알 수 있다.
// 일반 루프 안에서 return 사용하기
data class Person(val name: String, val age: Int)
val people = listOf(Person("Alice", 29), Person("Bob", 31))
fun lookForAlice(people: List<Person>) {
for (person in people) {
if (person.name == "Alice") {
println("Fround!")
return
}
}
println("Alice is not found") // "people" 안에 엘리스가 없으면 이 줄이 출력된다.
}
>>> lookForAlice(people)
Found!
위 코드는 forEach 함수를 대신 써도 안전하다.
// forEach에 전달된 람다에서 return 사용하기
fun looklForAlice(people: List<Person>) {
people.forEach {
if (it.name == "Alice") {
pritln("Found!")
return
}
}
println("Alice is not found")
}
람다 안에서 return을 사용하면 람다로부터 반환되는 게 아니라 그 람다를 호출하는 함수가 실행을 끝내고 반환된다. 그렇게 자신을 둘러싸고 있느 블록보다 더 바깥에 있는 다른 블록을 반환하게 만드는 return문을 넌로컬(non-local) return이라고 부른다.
8.3.2 람다로부터 반환: 레이블을 사용한 return
람다 식에서도 로컬 return을 사용할 수 있다. 람다 안에서 로컬 return은 for 루프의 break와 비슷한 역할을 한다. 로컬 return은 람다의 실행을 끝내고 람다를 호출했던 코드의 실행을 계속 이어간다. 로컬 return과 넌로컬 return을 구분하기 위해 레이블(lebel)을 사용해야 한다. return으로 실행을 끝내고 싶은 람다 식 앞에 레이블을 붙이고, return 키워드 뒤에 그 레이블을 추가하면 된다.
val people = listOf(Person("Alice", 29), Person("Bob", 31))
for lookForAlice(people: List<Person>) {
people.forEach label@{ // 람다 식 앞에 label을 붙인다.
if (it.name == "Alice") return@label // return@label은 앞에서 정의한 label을 참조한다.
}
println("Alice might be somewhere") // 항상 이 줄이 출력된다. (위에서 return이 되어도 lookForAlice 함수는 끝나지 않으므로)
}
>>> lookForAlice(people)
Alice might be somewhere
8.3.3 무명 함수: 기본적으로 로컬 return
무명 함수는 코드 블록을 함수에 넘길 때 사용할 수 있는 다른 방법이다.
// 무명 함수 안에서 return 사용하기
fun lookForAlice(people: List<Person>) {
people.forEach(fun (person) { // 람다 식 대신 무명 함수 사용
if (person.name == "Alice") return // "return"은 가장 가까운 함수를 카리키는데 이 위치에서 가장 가까운 함수는 무명 함수
println("${person.name} is not Alice")
}
}
>>> lookForAlice(people)
Bob is not Alice
무명 함수는 일반 함수와 비슷해 보인다. 차이는 함수 이름이나 파라미터 타입을 생략할 수 있다는 점 뿐이다.
// filter에 무명 함수 넘기기
people.filter(fun (person): Boolean {
return person.age < 30
})
무명 함수도 일반 함수와 같은 반환 타입 지정 규칙을 따른다. 위처럼 블록이 본문인 무명 함수는 반환 타입을 명시해야 하지만, 식을 본문으로 하는 무명 함수의 반환 타입은 생략할 수 있다.
// 식이 본문인 무명 함수 사용하기
people.filter(fun (person) = person.age < 30)
'Kotlin' 카테고리의 다른 글
[Kotlin in Action] 9.2 실행 시 제네릭스의 동작: 소거된 타입 파라미터와 실체화된 타입 파라미터 (0) | 2025.04.02 |
---|---|
[Kotlin in Action] 9.1 제네릭 타입 파라미터 (0) | 2025.04.02 |
[Kotlin in Action] 8.2 인라인 함수: 람다의 부가 비용 없애기 (0) | 2025.04.02 |
[Kotlin] 코틀린과 자바에서의 익명 함수와 람다 차이 (0) | 2025.04.01 |
[Kotlin] object는 어떻게 자바로 디컴파일 되는가 (0) | 2025.03.27 |
댓글