본문 바로가기

프로그래밍/코틀린

[코틀린] 고차함수 - 함수 참조와 익명 함수 이용

고차 함수에서 매개변수나 반환값으로 람다 함수를 많이 이용하지만,

함수 참조익명 함수를 이용해도 된다.

함수 참조를 이용한 함수 전달

고차 함수를 이용할 때 람다 함수 외에 함수 참조 연산자로 콜론 두개(::)를 이용할 수도 있다.

먼저 아래 소스코드는 람다코드로 작성한 코드이다.

 

fun hoFun6(argFun: (x:Int) -> Int){
    println("${argFun(10)}")
}

fun main() {
    hoFun6 { it * 5 }
}
[결과값]
50

 

고차함수를 선언하고, 매개변수로 함수를 받고 있다.

이렇게 선언한 고차 함수를 호출하면서 함수를 전달해야하는데

위의 소스코드에서는 it *5 라는 람다 함수를 넘겨서 10 * 5의 결과값을 출력하고 있다.

 

이런 소스 코드를 다음과 같이 함수 참조를 이용하여 작성도 가능하다.

 

fun hoFun6(argFun: (x:Int) -> Int){
    println("${argFun(10)}")
}

fun nameFun(x:Int):Int{
    return x * 5
}

fun main() {
    hoFun6(::nameFun)
}
[결과값]
50

 

nameFun이라는 함수를 선언하고, 이 함수에 (::) 함수 참조를 이용하여 고차함수의 매개변수로 전달한다.

이처럼 고차함수의 매개변수로 람다 함수 뿐만아니라 함수 참조를 이용할 수도 있다.

익명 함수를 이용한 함수 전달

람다 함수이름이 없는 함수이다.

전체 함수 내용을 중괄호로 묶고 ->를 이용하여 함수의 매개변수 부분과 함수 내용을 구분한다.

이름이 없으므로, 주로 고차 함수의 매개변수, 반환값으로 사용한다.

그런데, 이러한 람다 함수는 return 예약어를 사용하여 반환값을 명시할 수 없다.

 

val lambdasFun = {x:Int ->
    println("i am lambdas function")
    return x * 10 //error
}

 

이렇게 람다 함수의 함수 내용을 여러줄로 작성하게 되면 마지막 줄이 이 함수의 반환값이된다.

이때 return이라는 예약어를 사용하면 컴파일 에러가 발생하게 된다.

람다 함수에서는 return 예약어를 사용할 수 없으며 그런 이유로 반환 타입을 명시적으로 선언할 수도 없다.

 

람다 함수를 쓰는 곳이 대부분 고차 함수이므로,

이처럼 return을 명시적으로 선언하지 못하고 반환 타입을 지정할 수 없더라도

컴파일러가 마지막 줄을 보고 타입을 유추할 수 있으므로 별 문제 없이 사용할 수 있다.

하지만 때로는 명시적으로 반환과 관련된 부분을 선언하고 싶을 때가 있다.

 

이때, 익명함수를 사용하면된다.

익명함수는 단어 뜻 그대로 이름이 없는 함수를 의미한다.

 

val anonyFun1 = fun(x:Int):Int = x * 10

val anonyFun2 = fun(x:Int):Int {
    println("i am anonymous function")
    return x * 10
}

 

anonyFun1과 anonyFun2에 각각 fun 예약어를 이용하여 함수선언을 했고, 반환 타입도 명시했다.

그리고 함수 내용 안에서 return을 이용하여 반환값을 명시했다.

 

근데? 함수명이 없다.

이것은 람다함수일까?

 

람다함수는 중괄호{}를 감싸야하고 ->를 사용하여 매개변수와 함수 내용을 구분해야하는데 그렇지 않다.

바로 익명 함수로 선언한 함수이기 때문이다.

즉, 익명 함수는 일반함수 선언에서 함수명만 정의하지 않은 함수이다.

 

fun hoFun7(argFun : (Int)->Int){
    println("${argFun(10)}")
}

fun main() {
    hoFun7(fun(x:Int):Int = x * 5)
}
[결과값]
50

 

익명 함수도 람다 함수처럼 함수명이 없고, 고차 함수의 매개변수와 반환값으로 사용되고,

주로 반환값을 명시적으로 선언하려고 할때 이용된다고 알아두자!