람다 식 또는 람다는 다른 함수에 넘길 수 있는 작은 코드 조각을 뜻한다. 람다를 사용하면 공통 코드 구조를 라이브러리 함수로 뽑아낼 수 있다. 컬렉션 처리 과정에서 람다가 자주 사용된다.
“이벤트가 발생하면 이 헨들러를 실행하자”, “데이터 구조의 모든 원소에 이 연산을 적용하자”와 같은 생각을 코드로 표현하기 위해 동작을 변수에 저장하거나 다른 함수에 넘겨야 하는 경우가 자주 있다. 예전에 자바에서는 무명 내부 클래스를 통해 이런 목적을 달성했으나, 상당히 번거롭다.
함수형 프로그래밍에서는 함수를 값처럼 다루는 접근 방법을 택함으로써 이 문제를 해결한다. 클래스를 선언하고 그 클래스의 인스턴스를 함수에 넘기는 대신 함수형 언어에서는 함수를 직접 다른 함수에 전달할 수 있다. 람다 식을 사용하면 함수를 선언할 필요가 없고 코드 블록을 직접 함수의 인자로 전달할 수 있다.
자바에서 무명 내부 클래스를 이용하는 방법은 아래와 같다.
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
// 클릭 시 수행할 동작
}
});
코틀린에서 람다를 이용해 구현하면 아래와 같다. 이 예제는 람다를 메소드가 하나뿐인 무명 객체 대신 사용할 수 있다는 사실을 보여준다.
button.setOnClickListener {
// 실행할 동작
}
아래와 같은 클래스가 있다.
data class Person(val name:String, val age: Int)
Person 클래스로 이뤄진 리스트가 있고 그중에 가장 연장자를 찾고 싶다. 람다를 사용하지 않는다면 loop를 이용해 직접 검색을 구현해야 한다.
코틀린에서는 라이브러리 함수를 사용해 아래와 같이 구현할 수 있다.
fun main() {
val people = listOf(Person("Alice", 29), Person("Bob", 31))
println(people.maxBy { it.age })
}
모든 컬렉션에 대해 maxBy 함수를 호출할 수 있다. maxBy는 가장 큰 원소를 찾기 위해 비교에 사용할 값을 돌려주는 함수를 인자로 받는다. 중괄호로 둘러싸인 코드 { it.age }는 바로 비교에 사용할 값을 돌려주는 함수다. 이 코드는 컬렉션의 원소를 인자(it)로 받아서 비교에 사용할 값을 반환한다.
이런 식으로 단지 함수나 프로퍼티를 반환하는 역할을 수행하는 람다는 멤버 참조로 대치할 수 있다. 멤버 참조가 무엇인지는 아래에서 다 자세히 다룬다.
people.maxBy(Person::age)