고차함수란, 매개변수로 함수를 전달받거나 함수를 반환하는 함수를 말한다.
아래 소스에서는 fun 예약어와 hoFun이라는 함수명 그리고 ( )안에 매개변수, { } 안에 함수 내용을 선언했다.
fun hoFun(x1: Int, argFun: (Int) -> Int){
val result = argFun(x1)
println("x1 : $x1, result : $result")
}
fun main() {
hoFun(10, {x -> x * x} )
}
[결과값]
x1 : 10, result : 100
하지만 일반 함수와는 차이가 있다.
두 번째 매개변수는 argFun: (Int) -> Int로 선언했다.
매개변수로 함수를 받고자 함수 타입을 선언한 것이다.
코틀린에서는 일반적으로 데이터 타입을 선언할 때
x1: Int 형태로 콜론 ( : )을 기준으로 왼쪽에 변수명, 오른쪽에는 타입을 명시한다.
즉, argFun은 변수명이되고, (Int) -> Int는 타입이 된다.
타입에 맞는 함수를 매개변수로 받을 수 있다는 선언을 나타낸 것이다.
이처럼 매개변수로 함수를 전달받거나, 함수를 반환하는 함수를 고차 함수라고 한다.
그리고 이에 사용되는 몇 가지 기법들이 있다고 하는데 살펴보자.
함수 타입의 매개변수 대입
일반적으로 함수를 호출할 때 함수명 뒤에 ( )를 붙이고 ( )안에 인수를 작성한다.
그런데, 고차 함수의 매개변수가 함수 타입이라면 함수 호출 할 때 ( )를 생략이 가능하다.
fun hoFun1(argFun: (Int) -> Int) {
val result = argFun(10)
println("result : $result")
}
fun main() {
hoFun1({ x -> x * x })
hoFun1 { x -> x * x } // ( )이 생략이 가능하다.
}
위의 소스를 보면 매개변수는 하나인데, 함수 타입이다.
즉, 함수 하나를 매개 변수로 받는 함수이다.
이럴경우 ( )를 생략할 수 있게된다.
이런 형태의 함수 호출은 collection 타입을 이용할 때 자주보인다.
val array = arrayOf(10, 20, 30, 40)
fun main() {
array.filter { x -> x > 10 }
.forEach { x -> println(x) }
}
[결과값]
20
30
40
filter 함수의 매개변수는 (T) ->Boolean으로 선언되어 있다.
T는 Int 타입으로 변경이 되기에 (Int) -> Boolean으로 보면된다.
위의 코드에서 보다시피 함수 타입의 매개변수 하나를 가지는 함수이므로 호출할 때 ( )를 생략할 수 있다.
그렇다면? 함수 타입의 매개변수를 여러 개 선언할 때는 어떻게 될까?
fun hoFun1(no: Int, argFun1: (Int) -> Int, argFun2: (Int) -> Boolean) {
val result1 = argFun1(no)
val result2 = argFun2(no)
println("no : $no, result1 : $result1, result2 : $result2")
}
fun main() {
hoFun1(10, { it * it }, { it > 10 })
hoFun1(10, { it * it }) { it > 10 }
hoFun1(10) { it * it} {it > 10} //error
}
위의 소스에서는 매개변수가 3개인 고차 함수를 선언했다.
첫 번째 매개변수는 Int 타입이고
두 번째 매개변수와 세 번째 매개변수는 함수 타입이다.
첫 번째 고차함수 호출은 ( )안에 모두 넣은 경우이고
두 번째 고차함수 호출은 마지막 인수만 ( ) 밖에 선언한 것이고
세 번째 고차함수 호출은 두번째와 세번째 인수 보두 밖에 선언한 것이다.
하지만, 세 번째 고차함수 호출에서 에러가 발생하게된다.
그 이유는 고차 함수를 호출할 때 ( ) 밖에 작성할 수 있는 함수 타입은 맨 마지막 인수만 가능하다고 한다.
그렇기에 hoFun1(10) { it * it} {it > 10}는 에러가 발생하는 것이다.
함수 타입 기본값 이용
함수를 선언할 때 기본값을 지정할 수 있다.
고차 함수에도 가능하다.
fun hoFun2(
x1: Int,
argFun1: (Int) -> Int,
argFun2: (Int) -> Boolean = { x: Int -> x > 10 }
) {
val result1 = argFun1(x1)
val result2 = argFun2(x1)
println("x1: $x1, result1: $result1, result2: $result2")
}
fun main() {
hoFun2(10, {x -> x * x})
hoFun2(10, {x -> x * x}, {x -> x > 5})
}
[결과값]
x1: 10, result1: 100, result2: false
x1: 10, result1: 100, result2: true
argFun2에 기본값으로 {x : Int -> x > 10}을 선언했고
hoFun2(10, {x -> x * x})를 호출할 때 기본값의 함수가 정해져 실행된다.
'프로그래밍 > 코틀린' 카테고리의 다른 글
[코틀린] 고차함수 - 함수 참조와 익명 함수 이용 (0) | 2020.03.23 |
---|---|
[코틀린] 고차함수 - 함수 반환 (0) | 2020.03.19 |
[코틀린] 람다 표현식 (0) | 2020.03.04 |
[코틀린] 일급 객체로서의 함수 (0) | 2020.03.04 |
[코틀린] 순수함수로 정의 될 수 있는 함수 (0) | 2020.02.29 |