코틀린에서 함수는 일급객체입니다. 따라서 파라미터로 함수를 받거나 변수에 함수를 저장하는 등의 작업이 가능합니다
문법
val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }
# 생략 ver
val sum = { x: Int, y: Int -> x + y } # 1
val sum: (Int, Int) -> Int = { x, y -> x + y } # 2 (비추)
- 람다의 본문은 항상 중괄호({, })로 둘러싸여 있음
- 파라미터 타입은 람다 내 파라미터 부분 또는 람다 할당하는 변수 타입 둘중 한군데만 쓰면 되는데, 위 예제에서 1번처럼 쓰는걸 추천
- 화살표(->) 뒤에 본문이 나온옴
- 추론된 람다 리턴타입이 Unit(자바 void랑 비슷)이 아니라면, 람다 본문의 마지막 expression이 리턴타입이 됨
(람다 본문에는 return을 사용할 수 없음)
Trailing lambda
함수의 마지막 파라미터가 함수타입이라면 괄호 밖에 람다식을 쓸 수 있습니다.
fun <T, R> Collection<T>.fold(
initial: R,
combine: (acc: R, nextElement: T) -> R
): R {
// ...
}
위처럼 fold라는 확장함수가 있다고 했을 때
val items = listOf(1, 2, 3, 4, 5)
// val product = items.fold(1, { acc, e -> acc * e })
val product = items.fold(1) { acc, e -> acc * e } // preferred!
이런식으로 쓰는게 권장됩니다. 안 써도 동일하게 동작은 하는데 이게 코틀린 스타일이라고 하네요
run { println("...") }
만약 파라미터가 람다 하나뿐이라면 괄호도 생략 가능합니다
it
ints.filter { it > 0 } // this literal is of type '(it: Int) -> Boolean'
람다 파라미터가 한개이면서 타입을 추론할 수 있는 경우, 파라미터 선언부와 화살표(->)를 생략하고 it을 파라미터로 사용 가능합니다
언더스코어(_)
map.forEach { (_, value) -> println("$value!") }
// _는 사용 불가 ex) println(_) -> 안됨
람다 파라미터가 사용되지 않으면 언더스코어(_)로 대체할 수 있습니다.
코틀린에서 언더스코어는 예약어이기 때문에 일반적으로 변수명 등으로 사용할 수는 없습니다
파이썬에도 비슷한 용례가 있긴 한데 파이썬에서는 사실 _라는 변수를 만드는거라 코틀린과는 동작방식에 차이가 있습니다.
파이썬 쓰다보면 종종 _가 겹치는 문제가 발생하는데(ex. django에서 from ... import ugettext_lazy as _
) 그런 점에서 코틀린 방식이 더 나은거같네요
클로저(closure)
var sum = 0
ints.filter { it > 0 }.forEach {
sum += it
}
print(sum)
람다 내부에서 외부 변수(=captured variables)에 접근할 수 있습니다.
주의사항
- 람다가 이벤트 핸들러 등 비동기적으로 실행되는 함수로 사용된다면, 로컬변수에 대한 수정은 항상 람다가 실행된 후에 반영된다는 점을 명심하세요
fun tryToCountButtonClicks(button: Button): Int {
var clicks = 0
button.onClick { clicks++ }
return clicks
}
예를 들어 이런 함수는 항상 0을 반환할겁니다
- 람다가 어떻게 동작하는지 명확히 알아야 합니다
people.filter { it.age == people.maxBy(Person::age)!!.age }
예를 들어 위와 같은 코드는 사람 수만큼 최댓값을 구하는 연산을 반복합니다
val maxAge = peopel.maxBy(Person::age)!!.age
people.filter { it.age == maxAge }
따라서 이런식으로 바꿔줘야 합니다.
Reference
'프로그래밍 > Kotlin' 카테고리의 다른 글
[Kotlin] groupBy (0) | 2022.04.02 |
---|---|
[Kotlin] count, size 함수 (kotlin in action) (0) | 2022.04.02 |
[Kotlin] Delegation (위임) (0) | 2022.03.27 |
[Kotlin] local function (로컬 함수) (0) | 2022.03.26 |
[Kotlin] infix call (중위 호출) (0) | 2022.03.26 |