[Kotlin In Action] 5-1) 람다(lambda)의 유용함

ERyukSa·2023년 6월 21일
0

Kotlin In Action

목록 보기
1/9

람다는 변수에 저장하거나 함수에 전달할 수 있는 작은 코드 블록을 말한다. 간소화된 형태의 함수라고도 볼 수 있다.
람다의 목적은 무엇일까?

무명 내부 클래스(익명 객체)의 불편함

개발을 하다보면 일련의 동작을 변수에 저장하거나 함수에 넘겨야하는 상황이 있다. 예를 들어, 어떤 이벤트가 발생하면 실행시킬 핸들러를 등록하거나, 자료 구조의 모든 원소에 같은 연산을 수행하고 싶을 때가 그렇다.

예전 자바에서는 무명 내부 클래스로 이러한 목적을 달성했다. 하지만 객체를 선언하고 추상 메서드를 오버라이딩 해야 해서 상당히 번거롭다.

람다의 간결함

코틀린은 함수형 언어처럼 함수를 값처럼 다루는 접근 방법으로 이 문제를 해결한다. 무명 객체를 선언하지 않고 함수를 직접 다른 함수에 전달할 수 있게 되어 코드가 간결해진다. 여기에 람다를 사용하면 함수를 정의하지 않고 코드 블록만 전달하는 것이 가능해서 더욱 간결해진다.

두 방식을 비교해보자.

/* 자바: 무명 내부 클래스로 버튼 클릭 핸들러 구현 */
button.setOnClickListener(new OnClickListener() {
	@Override
    public void onClick(View view) {
    	/*버튼 클릭 시 수행할 동작*/
    }
}
/* 코틀린: 람다로 핸들러 구현 */
button.setOnClickListner { /* 버튼 클릭 시 수행할 동작 */ }

두 코드는 모두 버튼 클릭 이벤트에 대한 핸들러를 등록하는 같은 기능을 수행한다. 하지만 람다 등장 전의 자바는 onClick 내의 코드를 전달하기 위해 무명 객체를 선언하는 불필요한 일을 하는 반면, 람다는 실제로 필요한 코드 블록만을 전달하여 코드가 훨씬 간결하다.
(참고로 추상 메서드가 하나 뿐인 무명 객체에 대해서만 람다를 대신 사용할 수 있다)

람다 덕분에 간결한 코딩이 가능해진 또 하나의 예시를 살펴보자.

편리한 Collections 라이브러리

람다가 적극적으로 활용되는 대표적인 곳은 Collections(ex: 리스트) 라이브러리이다. 컬렉션을 다루는 작업은 자주 사용되는 일반적인 패턴이 많다. 예를 들어, 원소 중 최대 값을 구하거나, 전체 합을 구하는 작업이 그렇다. 컬렉션 라이브러리는 자주 쓰이는 여러 기능을 람다를 활용하여 사용자가 편리하게 사용할 수 있도록 지원하고 있다.

람다가 등장하기 전의 컬렉션 코드, 직접 구현하는 방식, 람다를 활용하는 방식을 비교해보자.

/* 자바: 무명 객체를 사용하여 비교 방식 전달*/
Collections.max(people, new Comparator<Person>() {
   @Override
   public int compare(Person p1, Person p2) {
      return p2.getAge() - p1.getAge();
   }
});
/* 코틀린: 직접 구현 */
fun findTheOldest(people: List<Person>) {
	var maxAge = 0
    var theOldest: Person? = null
    for (person in people) {
    if (person.age > maxAge) {
    	maxAge = person.age
        theOldest = person
    }
}

무명 객체를 사용하는 방식은 역시나 번거롭고, 직접 구현하는 것은 코드가 길어지고, 따라서 실수를 저지르기 쉽다. 예를 들어 비교 연산자를 잘못 사용하면 최소 값을 찾게 된다.

/* 코틀린: 컬렉션 라이브러리 사용*/
people.maxByOrNull { it.age }

반면, 컬렉션 라이브러리를 활용한 코드는 간결하고 어떤 작업을 하는 것인지 이해하기 쉽다.

참고로 maxByOrNull 컬렉션 함수는 비교에 사용할 값을 반환하는 함수를 인자로 받는다. 그리고 위 코드에서는 그 인자로 람다 { it.age }를 사용하고 있다. 그러면 maxByOrNull 수행 과정에서 people의 각 원소를 { it(Person).age }에 넣어서 반환 받은 age 값을 비교에 사용한다.

결론

람다 덕분에 더 간결하고 이해하기 쉬운 프로그래밍이 가능해졌다!

0개의 댓글