본문 바로가기
Kotlin

고차함수 (Higher-order-function) ,1급시민[객체,함수] (First-Class Citizen)

by 봄석 2019. 8. 29.

고차함수 (Higher-order-function) , fold ,reduce..

고차함수란 ?

고차함수에 대하여 알아보자

고차함수는 아래의 2가지 조건을 만족하는 함수입니다.

  1. 함수를 파라미터로 받는 함수
  2. 함수를 리턴하는 함수

 

1. 함수를 파라미터로 받는 함수 예

class HighOrderFunctionTest {

    fun simpleHOF(sum: (Int, Int) -> Int, a: Int, b: Int): Int = sum(a, b)

    @Test
    fun highOrderFunctionTest() {
        val result = simpleHOF({ x, y -> x + y }, 10, 20)
        Assert.assertEquals(30, result)
    }
}

 simpleHOF 함수는 Int,Int를 받아서 Int를 리텈하는 함수와 ,  a,b가 인자입니다.

 

fun <T, R> List<T>.map(transform: (T) -> R): List<R> {
val result = arrayListOf<R>()
for (item in this)
result.add(transform(item))
return result
}

또한 위와같은 map함수를 보았을때  인자 T를받아 반환값R을 리턴하는 함수를 매개변수로 받고 있는 것을 볼 수 있습니다

 

 

2.함수를 반환하는 예

fun <T> lock(lock: Lock, body: () -> T): T {
        lock.lock()
        try {
            return body()
        } finally {
            lock.unlock()
        }
    }

고차함수의 좋은 예로 lock을 많이 이야기하는데 , 

위 코드를 보게되면 함수 body를 받아서 함수를 반환하기전에 lock을 걸고 

함수를 반환, 그리고 최종적으로 lock을 풀게됩니다.

 

 

 

 

즉, 고차함수는 함수를 인자로 받거나 반환하는 함수입니다.

그리고 위 조건을 만족하기 위해서는 일급객체(First-Class Citizen) 이여야 합니다.

 

 

1급 객체(1급시민)란?
아래 3 가지조건을 충족한다면 1급 객체라고 할수 있습니다.

 

  1. 변수나 데이타 할당 할 수 있어야 한다.
  2. 객체의 인자로 넘길 수 있어야 한다.
  3. 객체의 리턴값으로 리턴 할수 있어야 한다.

 

Java와 Kotlin의 비교를 통하여 Kotlin 의 함수는 왜 1급 객체고 Java의 함수는 1급 객체가 아닌지 알아보겠습니다.

 

 

1. 첫번째 변수나 데이터에 할당할 수있어야 한다.

public class java {

    public static void test(){
        System.out.println("java");
    }

    public static void main(String[] args) {
        System.out.println("java");
//        Object a = test;
    }
}

kotlin은 a 에 type이 () -> Unit 인 test 함수 할당이 가능하지만, Java는 불가능 합니다.

val test1: () -> Unit = { println("firstCitizen") }

kotlin 은 위코드처럼 test1 변수에 함수를 할당할 수 있습니다.

 

객체의 인자로 넘길 수 있어야 한다.

val test2: (Int) -> Unit = { println("firstCitizen : ${it}") }
fun mytest(f: () -> Unit) {
    f.invoke()
}
mytest { Main.test2(1000) }
// firstCitizen : 1000


kotlin 은 function 함수의 인자로 함수타입을 전달 할 수 있습니다. 하지만 Java에서는 불가능 합니다

 

 

 

객체의 리턴값으로 리턴 할 수 있어야 한다.

fun mtest(): () -> Unit {
    return { println("firstCitizen") }
}

 

mtest  { println(“kotlin”) }, 즉 함수타입을 반환 합니다.

 

 

 

 

 

kotlin에서 함수는 변수나 data에 할당이 가능하며, 함수의 인자로 전달가능 하고, 함수의 리턴값으로도 사용 할 수 있습니다.

그렇기 때문에 kotlin의 함수는 1급 객체라고 할 수 있습니다.

반면 Java의 함수는 위 조건들을 만족하지 못하기 때문에 1급 객체라고 할수 없습니다.

'Kotlin' 카테고리의 다른 글

Sealed Class  (0) 2019.09.02
Fold, Reduce  (0) 2019.08.29
Reflection  (0) 2019.06.08
Kotlin 코드 Java로 디컴파일하기  (4) 2019.03.09
Collection에 대하여 -3 collection에 적용할수 있는 함수들  (4) 2019.03.09

댓글