F.R.I.D.A.Y.

Kotlin: 17 람다식(Lambda Expression) part1. Basic 본문

DEV/Kotlin

Kotlin: 17 람다식(Lambda Expression) part1. Basic

F.R.I.D.A.Y. 2020. 8. 23. 23:04
반응형

 이전 시간에 우리는 고차 함수에 대해 배웠습니다. 함수를 인자로 넘기는 방법도 배웠죠. 그런데 이전 시간의 범위에는 포함되지만, 조금 더 많은 이야기를 위해 따로 빼놓은 것이 있습니다. 바로 람다식(Lambda Expression)입니다. 이번 시간에는 이 람다식에 대해 배워보겠습니다.


함수를 인자로 넘기기

 이전 시간에 함수를 인자로 넘기는 방법에 대해 배웠습니다. 그때 어떻게 사용하던가요?

fun sum(a:Int, b:Int){
    println("입력 두 값의 합은 ${a + b}")
}
fun TestFunc(vSum:(Int, Int)->Unit){
    vSum(5, 4)
}
fun main(args:Array<String>){
    TestFunc(::sum)
}

 인자로 들어가는 함수 앞에 함수 참조 기호(::)를 입력했습니다. 덕분에 함수를 인자에 넣을 수 있지만, 불편합니다. 그럴 때는 람다식을 이용해 볼 수 있습니다.

람다식

 우리가 값을 함수의 인자로 넘길 때는 그 안에 변수만 넣는 것이 아니라 상수 값도 넣을 수 있었습니다. 함수는 불가능할까요? 아닙니다. 함수도 이번에 소개하는 람다식을 이용하면 비슷하게 이용할 수 있습니다.

 

기본 구조

 람다식의 기본 구조는 다음과 같습니다.

{v1, v2 -> expression}

 잘 이해가 안되죠? 그럴 것입니다. 일단 이 내용을 설명드리겠습니다. 위 코드를 함수로 변환해본다면 아래와 같습니다.

fun FuncName(v1:dataType, v2:dataType): returnType{
    expression
}

 람다식은 이름이 없는 함수이니  FumcName은 없는 것이지만, 이어서 나오는 v1, v2, expression의 경우 함수의 내용과 일치합니다.

 

 그런데 일반 함수의  v1, v2와 반환값은 자료형을 명시하고 있는데 반해서 람다식은 그렇지 않습니다. 필요가 없는 걸까요? 아니요, 람다식에도 분명 자료형은 필요합니다. 그리고 이미 컴파일러는 람다식의 정보를 알고 있습니다. 이미 작성이 되어있거든요.

 

 예시를 위해 람다식과 이 람다식을 이용하는 함수를 작성해보겠습니다.

fun TestLambda(lambda:(Int, Int) -> Int){
    println("3 + 5 = ${lambda(3, 5)}")
}

fun main(args:Array<String>){
    TestLambda({a, b -> a + b})
}

 람다식을 인자로 받게 되는 TestLambda 함수와 main함수에서 TestLambda 함수를 실행하면서 그 인자로 람다식[# {a, b -> a + b}]이 쓰인 것이 보입니다.

 

 TestLambda 함수의 인자 lambda 변수의 자료형이 여기에서 사용한 람다식의 매개변수 자료형을 가지게 됩니다.

 

반환값 전달

 함수에서 일련의 연산이 끝나면 가장 마지막에는 연산의 결과를 caller[# 특정 함수를 호출한 함수. 반대로는 callee가 있습니다.]에 전달합니다. 일반 함수에서는 return 키워드를 사용하면 값을 반환할 수 있었습니다. 그러나 지금 배우는 람다식은 return 키워드를 사용하지 않습니다.

 

{a, b -> a + b
         a * b}

 위와 같은 람다식이 존재한다고 생각해봅니다. 이 경우 람다식의 연산 결과는 a + b가 아닌 a * b가 됩니다. 즉, 마지막 연산식이 람다식의 반환 결과가 됩니다.

 

 실제 테스트를 진행해보겠습니다. 위에서 예시로 만들었던 함수를 아래처럼 수정해보겠습니다.

fun TestLambda(lambda:(Int, Int) -> Int){
    println("3 + 5 = ${lambda(3, 5)}")
}

fun main(args:Array<String>){
    TestLambda({a, b -> a + b
                        a * b})
}

play.kotlinlang.org

 a * b라는 연산결과가 전달되는 것을 볼 수 있습니다.

 

변수에 할당하기

변수에 람다식 할당하기

 람다식은 변수에 할당해 이름이 있는 함수처럼 사용할 수도 있습니다.

{a, b -> a + b}

 이 람다식을 plus라는 변수에 할당해보겠습니다.

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

 이제 이 plus를 사용해보겠습니다.

fun TestLambda(lambda:(Int, Int) -> Int){
    println("3 + 5 = ${lambda(3, 5)}")
}

fun main(args:Array<String>){
    val plus:(Int, Int) -> Int = {a, b -> a + b}
    TestLambda(plus)
}

 어떤가요? 람다식이 plus라는 변수에 할당되었습니다.

 매개변수가 존재하지 않는 람다식이 있을 수 있습니다. 이 경우에도 아래처럼 작성해 적용할 수 있습니다.

() -> Int     // 매개변수는 없으나 반환값이 Int 타입인 람다식의 자료형
(Int) -> Int  // Int 타입의 매개변수가 하나 있고 반환값이 Int 타입인 람다식의 자료형
(Int) -> Unit // Int 타입의 매개변수가 하나 있고 반환값은 없는 람다식의 자료형
() -> Unit    // 매개변수도 반환할 값도 존재하지 않는 람다식의 자료형

 여기에서 람다식에 매개변수가 없으 때는 화살표를 포함한 이전 부분은 작성하지 않아도 됩니다.

val printHello:()->Unit = {println("Hello world!")}

printHello()

다른 변수에 재할당하기

 람다식이 할당된 변수(A)를 다른 변수(B)에 또 대입하게 되면, 다른 변수(B)에서도 이미 람다식이 할당된 변수(A)처럼 같은 람다식을 사용할 수 있습니다.

val printHelloA:()->Unit = {println("Hello world!")}
val printHelloB:()->Unit = printHelloA
// val printHelloB = printHelloA
// printHelloB 변수는 printHelloA의 타입을 추론하기 때문에 굳이 자료형을 작성하지 않아도 됩니다.
printHelloA()
printHelloB()


 느리지만 여전히 진행하고 있습니다.. :b

Next.

 다음 포스트는 람다식의 조금 더 심도 있는 부분을 다룹니다.

 

Kotlin: 18 람다식(Lambda Expression) part2. Advance

 이전 시간에 람다식의 기초 부분을 배웠다면 이번엔 람다식을 조금 더 심도 있게 다뤄보겠습니다. 람다식의 이용 인자에 사용하기  인자에 사용하는 방법은 여러 가지가 있습니다. 이번에 소�

pang2h.tistory.com

 

# index

728x90
반응형

'DEV > Kotlin' 카테고리의 다른 글

Kotlin: 18 람다식(Lambda Expression) part2. Advance  (0) 2020.08.27
Kotlin: 16 고차 함수  (0) 2020.07.22
Kotlin: 15 함수형 프로그래밍  (1) 2020.06.06
Kotlin: 14 인라인 함수와 익명 함수  (0) 2020.04.06
Kotlin: 13 예외 처리  (1) 2020.04.05
Comments