게으른 컴공생
article thumbnail

Kotlin의 lambda expression

Kotlin에서 함수 유형 및 람다 표현식 사용

 

Kotlin에서 함수 유형 및 람다 표현식 사용  |  Android Developers

Kotlin에서 람다 표현식과 고차 함수의 사용 방법을 알아봅니다.

developer.android.com

위 페이지를 참고하여 kotlin의 특징적인 문법인 lambda expression에 대해 알아보자

 

개요

이번에 확인할 lambda expression의 내용 중 제일 핵심은

"함수도 하나의 자료형이고 리터럴로서 의미를 가진다"는 것이다

 

함수를 담은 변수

함수도 하나의 값이나 다름 없기 떄문에 변수에 함수를 저장할 수 있다

lambda expression은 함수도 하나의 값이라는 개념에서 시작한다

fun main() {
    val fun1Var = ::fun1
    fun1Var()
    fun2()
}

fun fun1(){
    println("this is fun1")
}

val fun2 = {
    println("this is fun2")
}

이런 식으로 말이다

::는 함수참조연산자라고 부른다

c로 생각해봤을 때 fun1자체는 주소값이고

그걸 타고 들어가는 -> 연산자라고 생각하면 되겠다

 

이때 fun1Var의 자료형은 () -> Unit이다

그러니까 자료형이 함수라는 뜻이다

 

lambda expression

위의 코드에서 특이한 점은 중괄호로 감싸진 '함수'를 하나의 값으로 취급해 변수에 대입한 것이다

이때 이 '함수'를 lambda expression이라고 하고

다른 언어에서의 익명함수와 유사하다

 

lambda expression의 구성은 다음과 같다

val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }

타입이 있는 앞부분과 실제 함수의 내용인 중괄호 부분이 있는데

이때 매개변수가 없으면 앞부분을 생략해서 우리가 위에서 본 중괄호만 남은 형태가 된다

중괄호 내부의 매개변수의 타입과 매개변수의 이름 마저도 생략할 수 있는데

더 알아보면서 예시를 확인해보자

 

함수를 리턴하는 함수

함수 또한 함수를 리턴값으로 가질 수 있다

다음 코드를 보자

fun main() {
    val yes = saySomething(true)
    val no = saySomething(false)
    yes()
    no()
}

fun saySomething(isYes: Boolean) : () -> Unit {
    if(isYes){
        return sayYes
    } else {
        return sayNo
    }
}

val sayYes: () -> Unit = {
    println("Yes")
}

val sayNo: () -> Unit = {
    println("No")
}

saySomething이라는 함수는 () -> Unit 형태의 자료형을 리턴한다

그러니까 saySomething이라는 함수는 함수를 리턴한다는 뜻이

 

 

함수인 매개변수

이번엔 심지어 매개변수 마저도 함수일 수도 있다

 

참고로 당연하지만 자료형이 함수인 변수도 nullable 하다 null일 수 있다는 뜻이다

만약 nullable한 함수를 받았고 이를 안전하게 호출하려면 함수명?.invoke()를 쓰자

아래 예시를 보자

fun main() {
    buySomething(checkWallet, 400)
    buySomething(null, 400)
}

fun buySomething(checkWallet: ((Int) -> Int)?, price: Int) {
    if(checkWallet != null){
        val money = checkWallet(4)
        if(money >= price)
            println("you can buy something")
        else
            println("you can't buy something")
    } else {
        println ("you forgot wallet")
    }
}

val checkWallet: (Int) -> Int = { coin ->
    coin*100
}

<출력결과>

you can buy something

you forgot wallet

 

checkWallet은 동전의 개수를 받아서 100만큼 곱해 리턴해주는 (Int) -> Int 타입의 함수이다

이 checkWallet이 바로 함수인 매개변수이다

buySomething은 checkWallet을 받아서 물건가격과 비교한다음 구매할 수 있는지 없는지를 출력한다

이때 checkWallet이 null 값이면 지갑을 안가져왔다는 문장을 출력한다

 

매개변수를 생략하면 it으로 명시할 수 있다

fun main() {
    buySomething(checkWallet, 400)
    buySomething(null, 400)
}

fun buySomething(checkWallet: ((Int) -> Int)?, price: Int) {
    if(checkWallet != null){
        val money = checkWallet(4)
        if(money >= price)
            println("you can buy something")
        else
            println("you can't buy something")
    } else {
        println ("you forgot wallet")
    }
}

val checkWallet: (Int) -> Int = {
    it*100
}

 

매개변수에 함수리터럴(=lambda expression)을 직접넣을 수도 있고

후행람다문법이라고 함수인 매개변수가 가장 마지막 매개변수라면 함수 호출 뒷부분에 람다표현식을 붙여놓을 수 있다

그동안 사용했던 Column같은 Composable에게 별다른 매개변수가 없을 때 그냥 중괄호만 있어도 됐던 이유다

BirthDayCard App - Column Container, 람다후행문법

fun main() {
    showMessage(returnMessage)
    showMessage({"this is message"})
    showMessage(){"this is message"}
}

fun showMessage(m: ()->String) {
    println(m())
}

val returnMessage: () -> String = {
    "this is message"
}

<출력결과>

this is message

this is message

this is message

 

repeat 함수

함수를 위한 for문인 repeat 함수가 있다(물론 아직 kotlin의 for문은 안 배웠지만..)

repeat함수의 상세는 아래와 같다

repeat(times: Int, action: (Int) -> Unit)

맨 마지막 매개변수가 함수이기 때문에 후행람다문법을 이용해서 이쁘게 쓸 수 있다

근데 action의 자료형 중에서 매개변수 부분이 Int인데 왜 그냥 암거나 다 넣을 수 있는 거지? 저 Int가 times인가?

암튼 repeat는 다음과 같이 이용할 수 있다

fun main() {
    repeat(5){
        sayHello()
    }
}

val sayHello: () -> Unit = {
    println("say hello")
}

<출력결과>

say hello

say hello

say hello

say hello

say hello

'기술 > 안드로이드' 카테고리의 다른 글

Android Studio Debugger  (0) 2022.10.14
Dice Roller App - remember API  (0) 2022.10.14
Kotlin의 class, property delegation  (0) 2022.10.14
Kotlin의 null  (0) 2022.10.14
Kotlin의 조건문  (0) 2022.10.14
profile

게으른 컴공생

@노나니노나

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그