관리 메뉴

너와 나의 스토리

[Kotlin] 람다 식(lambda expression)과 멤버 참조 본문

Programming Language/Kotlin

[Kotlin] 람다 식(lambda expression)과 멤버 참조

노는게제일좋아! 2021. 6. 16. 16:13
반응형

람다 식(lambda expression)

  • 다른  함수에 넘길 수 있는 작은 코드 조각
  • 람다를 사용하면 쉽게 공통 코드 구조를 라이브러리 함수로 뽑아낼 수 있다.
  • 자바에서는 일련의 동작을 변수에 저장하거나 다른 함수에 넘기기 위해
  • 익명 내부 클래스(anonymous inner class)를 사용하곤 했다.
    • 익명 내부 클래스를 사용하면 코드를 함수에 넘기거나 변수에 저장할 수 있기는 하지만 상당히 번거롭다.
  • 이와 달리 함수형 프로그래밍에서는 함수를 값처럼 다루는 접근 방법을 택함으로써 이 문제를 해결한다. 
    • 클래스를 선언하고 그 클래스의 인스턴스를 함수에 넘기는 대신 함수형 언어에서는 함수를 직접 다른 함수에 전달할 수 있다.
    • 람다 식을 사용하면 코드가 더욱더 간결해진다. 
      • 람다 식을 사용하면 함수를 선언할 필요 없이 코드 블록을 직접 함수의 인자로 전달할 수 있다.

 

Example: 버튼 클릭에 따른 동작 정의하기

  • onClick() 메서드가 들어있는 OnClickListener를 구현해야 한다. 
  • 익명 내부 클래스로 리스너 구현하기
button.setOnClickListener(new OnClickListener() {
  @Override
  public void onClick(View view){
  	// 클릭 시 수행할 동작
  }
})
  • 람다로 리스너 구현하기
button.setOnClickListener {
        // 클릭 시 수행할 동작
}

 

람다와 컬렉션

  • 컬렉션을 다룰 때 수행하는 대부분의 작업은 몇 가지 일반적인 패턴에 속한다. 
  • 따라서 그런 패턴은 라이브러리 안에 있어야 한다. 

 

람다 식의 문법

  • 람다는 값처럼 여기저기 전달할 수 있는 동작의 모음이다. 
  • 람다 식 문법: {파라미터 -> 본문}
    • 예: { x: Int, y: Int -> x+y }
    • 코틀린 람다 식은 항상 중괄호로 둘러싸여 있다. 
  • 람다 식을 변수에 저장할 수 있다.
val sum = { x: Int, y: Int -> x + y }
println(sum(1, 2)) // output: 3
  • 람다 식을 직접 호출할 수도 있다.
run { println(42) } // output: 42

 

예: Person 클래스 존재. Person 객체가 list 형태로 저장된 변수 people에서 나이가 가장 많은 사람(Person)을 찾아낸다.

  • 코틀린에서 제공하는 maxByOrNull 라이브러리 함수를 사용
  • maxBy()는 deprecated. 대신 maxByOrNull 쓰라고 intelliJ가 말해줌
data class Person(val name: String, val age: Int)

fun main(args: Array<String>) {
    val people = listOf(Person("Alice", 29), Person("Bob", 31))
    val older = people.maxByOrNull { p: Person -> p.age }
    println(older) // output: Person(name=Bob, age=31)
}
  • maxByOrNull 활용
// 라이브러리 함수 사용 -> 람다의 파라미터 이름을 디폴트 이름인 it으로 바꿀 수 있다.
people.maxByOrNull { it.age }

// 멤버 참조를 사용해 컬렉션 검색
people.maxByOrNull(Person::age)

// 람다 사용
people.maxByOrNull { p: Person -> p.age }

// 람다 파라미터 타입 제거
people.maxByOrNull { p -> p.age }

 

본문이 여러 줄이 람다 식

val sum = { x: Int, y: Int ->
    println("Computing the sum of $x and $y: " + (x + y))
}
sum(3, 5)
// output: Computing the sum of 3 and 5: 8

 

forEach 표준 함수: 컬렉션의 모든 원소에 대해 람다를 호출

  • messages에 있는 모든 String마다 print
fun printMessagesWithPrefix(messages: Collection<String>, prefix: String) {
    messages.forEach {
        println("$prefix $it")
    }
}
  • 람다 안에서 바깥 함수의 로컬 변수 변경
    • if문을 비롯해 좀 더 복잡한 연산도 람다 안에서 가능하다.
fun printMessagesWithPrefix(messages: Collection<String>, prefix: String) {
    var clientErrors = 0
    var serverErrors = 0
    messages.forEach {
        if (it.startsWith("4")) {
            clientErrors++
        } else if (it.startsWith("5")) {
            serverErrors++
        }
    }
}

 

 

 

 

출처:

- [Kotlin IN ACTION]

 

반응형
Comments