반응형

8. Lambda

람다식은 우리가 마치 value처럼 다룰 수 있는 익명함수이다. value처럼 다룬다는게 무슨 뜻이냐?

 1) 메소드의 파라미터로 넘겨줄 수 있다. 2) return 값으로 사용할 수 있다.

람다는 기본적으로 val 함수이름 : 타입 = { 파라미터 -> 실행할 코드 } 와 같은 형태로 작성한다.

fun main(){

    println(square(12)) // 144 출력
    println(square2(12)) // 144 출력
    println(nameAge("Hyunsoo", 24)) // my name is Hyunsoo I'm 24 출력

}

val square : (Int) -> (Int) = {number -> number*number}
// Int 가 두번 쓰인 이유는 Int를 받고(파라미터) Int를 반환해서(반환값)!!
// number는 자동으로 Int로 추론

val square2 = {number : Int -> number*number}
// 람다식을 이렇게 사용할수도 있다. Int만 파라미터로 받기 때문에 반환값은 자동 추론(Int)

val nameAge = {name : String, age : Int ->
    "my name is ${name} I'm ${age}"
    // 나이랑 이름이 파라미터로 넘겨짐
    // 람다에서는 마지막에 있는 코드 줄이 리턴값이다
}

위의 코드는 기본적인 람다 사용법이다. 이처럼 중괄호를 사용하면 Int, String을 선언하듯이 함수 역시 변수에 넣을 수 있다는 것을 알아두자. 

 코틀린은 기존 클래스에 메소드를 추가할 수 있는데 이를 확장 함수라고 한다. ' 이 클래스 정말 좋은데 몇가지만 추가하고 싶어! ' 라는 생각이 들 때 확장 함수를 사용하면 될 것 같다.

fun main(){

    val a = "Joyce said "
    val b = "HyunSoo said "

		// a, b가 String 클래스이기 때문에 확장함수인
		// pizzaIsGreat 함수를 사용 가능
    println(a.pizzaIsGreat())
    // Joyce said Pizza is the best! 출력
    println(b.pizzaIsGreat())
    // HyunSoo said Pizza is the best! 출력
}

// 익명함수, String함수를 확장한다.
val pizzaIsGreat : String.() -> String = {
    this + "Pizza is the best!"
    // this 가 가리키는 것 String.()에서 String 그 자체를 기리킨다.
}

 이런식으로 String 클래스에 무엇인가 하나 추가하고 싶다면 확장 함수를 사용하여 작성할 수 있다.

fun main(){

   println(extendString("Ariana", 27))
   // I am Ariana and 27 years old 출력
}

fun extendString(name : String, age : Int) : String {

    val introduceMyself : String.(Int) -> String = {"I am ${this} and ${it} years old"}
    return name.introduceMyself(age)
    // this는 확장함수가 불러줄 오브젝트 it은 Int가 it으로 바뀐것
    // it이 사용된 이유는 파라미터가 Int 하나이기 때문에 input파라미터 대신 it을 사용한 것이다.
    // this가 가리키는 것은 확장함수가 콜하는 오브젝트, it은 파라미터가 1개 일 때 대신해서 쓸 수 있다.
}

 it은 파라미터가 하나만 있을 때 사용할 수 있는데 그 파라미터 대신 it을 사용할 수 있다.

 람다는 마지막 표현식(마지막 한 줄)이 Return값을 의미한다.

fun main(){

    println(calculateGrade(0))
    // fail 출력
    println(calculateGrade(41))
    // pass 출력
    println(calculateGrade(1000))
    // error 출력

}

// input파라미터(Int)는 여러개가 있을 수 있기 때문에 항상 소괄호를 사용해주어야함.
// 리턴값(String)은 항상 타입이 하나이기 때문에 괜찮다.
val calculateGrade : (Int) -> String = {
    when (it) { // 파라미터가 1개이기 때문에 it 사용
        in 0..40 -> "fail"
        in 41..70 -> "pass"
        in 71..100 -> "perfect"
        else -> "error"
        // 이함수는 string을 반드시 반환해야하기 때문에(반환값 존재) else를 써주어야한다.
    }
}

람다를 표현하는 두가지 방법

fun main(){

    val lambda = {number : Double -> number == 4.3213}
    println(invokeLambda(lambda)) // false 출력

    println(invokeLambda({ it > 3.22 }))
		// it은 파라미터(하나만 있을 때)를 가리키기 때문에 (lambda)를 가리
    // 람다 리터럴 방식이라고 함다 별도의 람다 함수를 설정해 주지않고 바로 사용킴
    // true 출력

    // 함수의 마지막 파라미터가 람다식일경우에는 ()를 생략하고 {}만 사용할수 있다.
		// invokeLambda 함수의 경우에는 파라미터가 하나이기 때문에
		// 처음이자 마지막 파라미터가 람다식이라서 ()를 생략 가능
    println(invokeLambda { it > 3.22 }) // true
}

// 메소드의 파라미터로 넘겨줄 수 있다.
// Double을 받고 Boolean을 리턴하는 lambda함수를 파라미터로 받음
fun invokeLambda(lambda : (Double) -> Boolean) : Boolean {
    return lambda(5.2343)
    // invokeLambda 함수는 Boolean타입을 리턴하는데
    // 파라미터로 넣는 람다식을 사용할 것인데 람다에 5.2343을 넣어서 리턴되는 불리언 값을
    // invokeLambda의 리턴 값으로 사용하겠다는 뜻
}

위에 작성된 코드 및 설명들은

코틀린 3강으로 끝내기 - 2편 고급 문법

에서 코틀린 강의 영상을 보며 정리한 내용입니다.

반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기