Kotlin은 함수형 패러다임을 지원합니다.
함수형 프로그래밍은 코드를 좀 더 유연하고 확장성 있게 만듭니다.
고차 함수는 함수를 인자로 받거나 반환할 수 있습니다.
이때 함수 타입과 Lambda가 활용됩니다.
먼저 아래는 일반적인 함수 유형입니다.
파라미터로 전달된 배열의 숫자 합을 계산하는 함수입니다.
fun sum(numbers: IntArray): Int { var result = numbers.firstOrNull() ?: throw IllegalArgumentException("Empty array") for (i in 1..numbers.lastIndex) result += numbers[i] return result } fun main() { println(sum(intArrayOf(1, 2, 3))) //6 }
이 함수는 오직 숫자의 합만을 구할 수 있습니다.
그런데 고차 함수를 적용하면, 조금 더 다양한 기능을 구현할 수 있습니다.
fun aggregate(numbers: IntArray, op: (Int, Int) -> Int): Int { var result = numbers.firstOrNull() ?: throw IllegalArgumentException("Empty array") for (i in 1..numbers.lastIndex) result = op(result, numbers[i]) return result } fun aggregateSum (numbers: IntArray) = aggregate(numbers, { result, op -> result + op }) fun aggregateMax (numbers: IntArray) = aggregate(numbers, { result, op -> if (op > result) op else result }) fun main() { println(aggregateSum(intArrayOf(1, 2, 3))) //6 println(aggregateMax(intArrayOf(1, 2, 3))) //3 }
고차 함수를 적용하면 파라미터로 전달되는 함수 타입에 따라 유연한 계산이 가능합니다.
고차 함수에서 이미 함수 타입을 적용해 봤습니다.
함수 타입은 함수 파라미터 뿐 아니라, 변수에도 적용이 가능합니다.
변수에 적용된 함수 타입은 마치 함수처럼 호출됩니다.
val lessThan: (Int, Int) -> Boolean = { a, b -> a < b} println(lessThan(1, 2)) //true val sum: (Int, Int) -> Int = { a, b -> a + b} println(sum(1, 2)) //3
람다식은 함수 정의와 달리 반환 타입을 지정할 필요가 없습니다.
람다식 본문에서 반환되는 타입을 자동으로 추론합니다.
물론 반환 타입을 지정할 수도 있습니다.
var moreThan = { a:Int, b:Int -> a > b } println(moreThan(1, 2)) //false val moreThan: (Int, Int) -> Boolean = { a, b -> a > b} println(moreThan(1, 2)) //false
익명 함수는 일반 함수와 비슷하지만, 함수 이름과 파라미터 타입을 지정할 필요가 없습니다.
별도 함수로 코드를 따로 빼지 않고, 작성 중인 코드에 이어서 지정할 수 있습니다.
val thisYear: (String) -> String = { "This year: $it" } println(thisYear("2023")) //This year: 2023