기타/AOS, Kotlin

[코틀린] 코틀린의 '람다'(Lamda) 살펴보기

kyxxn 2023. 7. 29. 01:22
728x90

이번 글을 적기에 앞서 살펴볼 내용은 다음과 같다.

 

1. 람다 (Lamda)

2. 데이터 클래스

3. Companion Object

4. Object

 

Lamda (람다)

1. 람다 식은 마치 우리가 value처럼 다룰 수 있는 익명 함수이다. + 간결한 함수 표현 방식

2. 함수를 선언하지 않고도, 코드 내에서 함수를 정의하고 사용할 수 있게 해준다.

3. 메소드의 파라미터로 넘겨줄 수 있다. ex) fun maxBy(a:Int) => a : Int를 적은 파라미터 자리에 Fun을 넣을 수 있음.

4. return 값으로도 사용할 수 있다.

람다의 기본 형태 정의
val lamdaName : Type = {argumentList -> codeBody}

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

위 두 람다 식은 같은 람다 식임
즉, val 람다 함수명 : 람다 함수 리턴값 자료형(R_Value에서 명시할 경우 생략가능) 
= {또 다른 변수명 : 변수 자료형 -> 리턴값}

// 문자와 정수를 같이 받을 경우
fun main(){
    val nameAge = {name : String, age : Int ->
        "내 이름은 ${name}이고 ${age}이다"
    }
    println(nameAge("효준", 22))
}
위 코드의 경우 nameAge의 반환 타입은 String이 된다.
항상 { A -> B}에서 맨 마지막인 B의 데이터 타입을 따른다.

람다와 확장 함수

: 기존의 클래스에 몇 개만 추가하고 싶을 때 주로 사용

val lamdaExtend : String.() -> String = {
    this + "를 메소드처럼 쓸 수 있게 됨"
}

fun main(){
    val a = "테스트 1번"
    println(a.lamdaExtend())
}
람다 식의 자료형을 String.() 로 하면, 마치 메소드를 추가하는 느낌
람다 식의 리턴값 자료형은 String.

위 코드에서 a는 String 클래스의 객체이다.
a.lamdaExtend()을 하여 마치 String 클래스의 메소드를 호출하는 것처럼 씀.
그럼 그 메소드의 this는 a에 대한 문자열.

fun extendString(name : String, age : Int) : String{
    val introduceMyself : String.(Int) -> String = {
        "I am ${this} and ${it} years old"
    }
    return name.introduceMyself(age)
}

fun main(){
    println(extendString("박효준", 22))
}

introduceMyself 메소드가 String.(Int)로 정수타입 매개변수 하나를 받고 사용하는데,
그러면 람다식 내부에서 매개변수가 하나 일 경우, it을 사용하여 대체할 수 있음.
it을 쓰기 싫으면 람다식 내부에서 a -> "~~"

 

람다의 반환 (Return)

val calculateGrade : Int -> String = {} // 에러
val calculateGrade : (Int) -> String = {} // O
위 코드가 에러나는 이유는, 앞에 매개변수는 여러 개 올 수 있으므로 ()를 사용
Return 값은 하나기에 소괄호 안 씌워줘도 됨.

val calculateGrade : (Int) -> String = {
    when(it){
        in 1..40 -> "1~40점은 탈락"
        in 41..100 -> "굿굿"
        else -> "Error"
    }
}
람다식의 매개변수가 하나이므로 it 사용 가능.
it이 1..40 안에 있으면(in) -> 출력.
항상 else 문을 써줘야 함

 

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

fun invokeLamda(lamda : (Double) -> Boolean) : Boolean{
    return lamda(5.2)
}

fun main(){
    val check : (a : Double) -> Boolean = {
        a ->
        when(a){
            in 0.0..40.50 -> false
            else -> true
        }
    }
    println(invokeLamda(check))
}

위처럼 만들어진 람다식을 함수의 매개변수로 넣을 수도 있음.
매개변수에서는 람다식에 대한 입력과 반환값 타입이 맞아야 함.

val check = {
        a : Double ->
        when(a){
            in 0.0..40.50 -> false
            else -> true
        }
    }
이렇게 조금 더 깔끔하게 적기 ㄱㄴ

val lamda = {
        number : Double -> number == 4.13
    }
println(invokeLamda(lamda))
이렇게하면 number랑 4.13이 같으면 true.

// 또는 매개변수로 람다를 넣지 않고 임시 객체(?) 넘겨주기
fun invokeLamda(lamda : (Double) -> Boolean) : Boolean{
    return lamda(4.13)
}

fun main(){
    println(invokeLamda({it > 3.22})) // it은 매개변수가 하나.
		println(invokeLamda{ it > 3.22 } ) // 위 코드와 동일함.
		//매개변수가 람다식을 받을 경우, 함수호출할 때 소괄호가 아닌 {}로 사용 가능
}