티스토리 뷰

반응형
SMALL

람다식(람다 함수)은 익명 함수(Anonymous Function)를 지칭하는 용어입니다. 함수형 프로그래밍이 아니더라도 람다식(람다함수)을 사용할 수 있지만 함수형 프로그래밍에서는 람다 함수가 고차함수의 매개변수(Parameter)나 반화값(Return Value)으로 사용됩니다.

고차 함수가 무엇인지는 조금 후에 알아보도록 하고 코틀린에서 람다식이 무엇인지 알아보기로 하겠습니다.

 

람다식 (람다 함수)

fun 함수이름(매개변수) { 함수내용 }

코틀린에서 함수를 작성하는 방식은 위와 같습니다. 람다 함수는 fun이라는 키워드와 함수 이름을 생략하고 선언합니다.

{ 매개 변수 -> 함수 내용 }

람다 함수는 다음과 같은 규칙을 바탕으로 정의합니다.

1. 람다 함수는 항상 { }로 감싸서 표현해야 한다.
2. { } 안에 '->' 표시가 있고 '->' 왼쪽은 매개 변수, '->' 오른쪽은 함수 내용이다.
3. 매개변수 타입을 선언해야 하고 추론할 수 있을 때에는 생략할 수 있다.
4. 함수의 Return Value는 함수 내용의 마지막 표현식이다.

간단하게 람다 함수의 사용 방법에 대해 알아보겠습니다.

fun plus(a: Int, b: Int): Int {
	return a + b
}

간단하게 두 수를 입력받아 두 수를 더한 값을 반환하는 함수입니다. 이 함수를 람다 함수로 표현하면 다음과 같습니다.

val plus = { a: Int, b: Int -> a + b }

fun main(args: Array<String>) {
    val result = plus(1, 2)
}

함수형 프로그래밍에서 함수는 일급 객체로서 다른 변수에 대입하거나 반환 값으로 사용될 수 있습니다. 

아니면 다음과 같이 정의하자마자 호출하는 방법도 사용할 수 있습니다.

{ print("Hello World") }()

run { print("Hello World") }

이렇게 익명 함수로 선언하면 한 번만 실행할 수 있으며 이후에는 다시 호출할 수 없습니다.

 

매개 변수가 없는 람다 함수의 정의

람다 함수를 정의할 때 매개 변수가 없으면 '->' 기호를 생략합니다.

val sum = { 10 + 20 }

함수 내용이 여러 줄일 때의 반환 값

함수 내용이 여러 줄일 경우에는 함수의 가장 마지막 줄이 반환 값이 됩니다.

val sum = { a : Int, b : Int ->
    println("call sum()")
    a + b
}

 

함수 타입

함수 타입 선언

함수형 프로그래밍에서는 함수에도 변수처럼 타입이 존재합니다. 함수 타입이란 매개변수와 반환값의 형식을 말합니다. 함수가 몇개의 매개 변수를 가져야 하며 각각 어떤 타입이어야 하는지, 또한 반환 값은 어떤 타입이어야 하는지에 대한 명시를 함수 타입이라고 합니다.

val lambdaFunction: (Int) -> Int = { x: Int -> x * 10 }

위 코드는 int형의 매개변수를 받고 ( '(Int)' ), Int 형의 데이터를 반환하는 ( '-> Int' ) 함수 타입을 의미합니다.

 

typealias를 이용한 타입 정의

typealias MyType = (Int) -> Boolean
val isEven: MyType = { it % 2 == 0 }

(Int) -> Boolean 이라는 타입을 MyType이라는 이름으로 alias 한 후에 사용하는 코드입니다.

 

매개 변수 타입 생략

일반적으로 람다 함수를 정의할 때에는 매개 변수의 타입을 선언하여 작성하지만, 매개 변수 타입을 생략할 수 있습니다. 

함수 타입을 작성하면 매개 변수 타입을 생략할 수 있습니다.

val lambdaFunction = {x -> x + 10} // ERROR
val lambdaFunction: (Int) -> Int = { x -> x + 10 }

위 코드는 함수 타입을 선언하지 않아도 에러가 발생하고 있으며 아래의 코드처럼 사용하면 에러가 사라집니다.

 

it을 이용한 매개변수 이용

람다 함수를 정의할 때 매개 변수가 1개일 경우에는 it이라는 키워드를 사용하여 매개 변수를 생략할 수 있습니다.

val lambdaFunction: (Int) -> Int = { x -> x + 10 }

val lambdaFunction: (Int) -> Int = { it + 10 }

만약 함수의 타입이 정의되지 않았다면 it을 사용할 경우 컴파일 에러가 발생하게 됩니다.

 

멤버 참조 이용

람다 함수를 작성할 때 멤버 참조(Member Reference)를 사용하면 조금 더 쉽게 작성할 수 있습니다.

멤버 참조는 콜론 2개(::)를 이용하여 타입을 명시하는 기법으로 정확하게는 Reflection이라고 부릅니다.

람다 함수를 멤버 참조로 정의하려면 함수의 매개변수로 객체 타입을 하나 받고, 그 객체의 멤버를 그대로 반환해야 합니다.

fun main(args: Array<String>) {
    class User(val name: String, val age: Int)
    
    val lambda: (User) -> Int = { user: User -> user.age }
    println("lambda return : ${lambda(User("KIM", 25))}")
}

it을 사용하면 조금 더 줄여볼 수 있습니다.

val lambda: (User) -> Int { it.age }
println("lambda return : ${lambda(User("KIM", 25))}")

이 코드를 멤버 참조를 이용한다면 어떻게 될까요?

val lambdaFunction: (User) -> Int = User::age
println("lambda return : ${lambda(User("KIM", 25))}")

it.age를 User::age로 표현할 수 있습니다.

 

 

 

 

 

 

 

 

 

 

반응형
LIST
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함