brunch

You can make anything
by writing

C.S.Lewis

by 서준수 Dec 20. 2017

코틀린 Higher-Order Functions #1

빠르게 살펴보기

Higher-Order Functions


 코틀린은 Higher-Order Functions(이하 고차 함수)를 제공합니다. 고차 함수는 함수의 파라미터로 함수를 받거나 함수를 리턴하는 함수입니다.


 먼저 레퍼런스에 소개된 코드를 한 번 보겠습니다.                    


fun <T> lock(lock: Lock, body: () -> T): T {

    lock.lock()

    try {

        return body()

    }

    finally {

        lock.unlock()

    }

}



 이 코드를 봐서는 고차 함수를 이해하기에 직관적이지 않아 보입니다. 왜냐하면 어떠한 결과가 나오는지 정보가 부족하기 때문입니다. 좀 더 구체적인 예제가 필요할 것 같습니다.


 다만 위 예제에서 알아야 할 부분이 있습니다. 형태를 보면 파라미터로 함수를 받고 있고 리턴값으로 함수를 사용하고 있습니다.


 파라미터로 사용된 함수 body: () -> T 의미


body: 파라미터명

() -> T 파라미터가 없는 함수를 의미하며 리턴 타입은 T(generic)



 이 정도만 알고 예제를 만들어 보았습니다. 간단한 예제인데 이 코드를 작성하기까지 많은 시간이 소요되었습니다. 그 이유는 바로 공부하는 순서가 절차지향적이지 않아서 발생한 문제입니다. 다음 예제를 작성하면서 Function Reference 부분을 찾아보게 되었네요.


 일단 제가 먼 길 둘러간, 소위 삽질한 결과를 다음 예제로 설명드리겠습니다.                    


fun main(args: Array<String>) {

    println(apply("Kim", {increase(3)}))

}


fun increase(num: Int) : Int {

    println("num $num")

    return num + 10

}


fun apply(name: String, body: (Int) -> Int) : Int {

    println("name $name")

    return body(0)

}


name Kim

num 3

13



 고차 함수는 파라미터로 함수를 가질 수 있다고 하였습니다. 여기서 고차 함수는 apply()이고 두 번째 파라미터에서 함수를 받고 있습니다. 때 body 함수는 (Int) -> Int이기 때문에 파라미터로 Int 타입을 갖고 리턴 타입도 Int입니다.


 그러면 body에 그에 상응하는 함수를 넘겨줄 수 있겠죠? 그래서 increase 함수를 하나 생성하였습니다. 물론 increase 함수는 파라미터로 Int 타입을 리턴 타입으로 Int 타입을 가지고 있습니다.


 이제 apply 함수를 사용해보고 싶습니다. 제가 난관을 겪었던 곳은 지금부터입니다. 도대체 increase 함수를 어떻게 넘겨주는 걸까요?


 결과적으로 위 예제처럼 println(apply("Kim", {increase(3)})) 이렇게 중괄호를 사용하였습니다. 그런데 이것은 람다 표현식(lambda expression)입니다. 중괄호 없이 사용하려고 하면 type mismatch로 사용이 안됩니다. 왜냐하면 앞서 말했던 Function Reference를 보면 함수를 다른 함수에 값으로 넘겨주려면 ::을 사용하여야 합니다.                    


fun main(args: Array<String>) {

    println(apply("Kim", ::increase))

}


fun increase(num: Int) : Int {

    println("num $num")

    return num + 10

}


fun apply(name: String, body: (Int) -> Int) : Int {

    println("name $name")

    return body(3)

}


name Kim

num 3

13



 이런 식으로 넘겨주니 increase에 인자값을 줄 수가 없었습니다. 물론 apply에서 추가적으로 increase에서 사용할 인자를 받아서 사용하는 방법도 있겠죠. 하지만 인자값을 넘겨줄 수 있는 방법이 궁금하네요. (좀 더 찾아보고 공부해야겠습니다.)

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari