2022-03-10 작성완료
Higher-Order Function은 다른 함수를 파라미터로 가지고/가지거나 함수를 반환하는 함수이다.
fun calculate(x: Int, y: Int, operation: (Int, Int) -> Int): Int { // 1
return operation(x, y) // 2
}
fun sum(x: Int, y: Int) = x + y // 3
fun main() {
val sumResult = calculate(4, 5, ::sum) // 4
val mulResult = calculate(4, 5) { a, b -> a * b } // 5
println("sumResult $sumResult, mulResult $mulResult")
}
x
와 y
를 가진다. 그리고 다른 함수 operation
을 파라미터로 가진다. operation
파라미터와 리턴 타입 또한 선언에서 정의된다.operation
의 결과를 리턴한다.operation
signature와 일치하는 함수를 선언한다.::sum
을 전달해 고차 함수를 호출한다. ::
는 코틀린에서 함수를 이름으로 참조하는 표기법이다.fun operation(): (Int) -> Int { // 1
return ::square
}
fun square(x: Int) = x * x // 2
fun main() {
val func = operation() // 3
println(func(2)) // 4
}
(Int) -> Int
는 square
함수의 파라미터와 반환값을 나타낸다.operation
을 호출한다. 이 func
는 operation
에 의해 반환된 square
가 된다. func
를 호출한다. square
함수가 실제로 실행된다. Lambda Functions("람다")는 애드혹 함수를 만드는 간단한 방법이다. 타입 추론과 암묵적 it
변수 덕에, 람다는 많은 경우 아주 간결하게 표시될 수 있다.
// All examples create a function object that performs upper-casing.
// So it's a function from String to String
val upperCase1: (String) -> String = { str: String -> str.uppercase() } // 1
val upperCase2: (String) -> String = { str -> str.uppercase() } // 2
val upperCase3 = { str: String -> str.uppercase() } // 3
// val upperCase4 = { str -> str.uppercase() } // 4
val upperCase5: (String) -> String = { it.uppercase() } // 5
val upperCase6: (String) -> String = String::uppercase // 6
println(upperCase1("hello"))
println(upperCase2("hello"))
println(upperCase3("hello"))
println(upperCase5("hello"))
println(upperCase6("hello"))
(String) -> String
타입(함수 타입) 변수에 할당된다.it
변수를 사용할 수 있다. 이것은 it
타입이 추론될 수 있을 때(자주 있는 일이다) 특히 유용하다.::
를 쓸 수 있다.코틀린은 어떤 클래스에든 확장(extensions) 메커니즘으로 새 멤버를 추가할 수 있다. 즉, 확장에는 두 가지 유형이 있다: 확장 함수(extension functions)와 확장 프로퍼티(extension properties)이다. 그것들은 일반적인 함수와 프로퍼티처럼 보이지만 한 가지 중요한 차이점이 있다: 확장하는 타입을 지정해야 한다.
data class Item(val name: String, val price: Float) // 1
data class Order(val items: Collection<Item>)
fun Order.maxPricedItemValue(): Float = this.items.maxByOrNull { it.price }?.price ?: 0F // 2
fun Order.maxPricedItemName() = this.items.maxByOrNull { it.price }?.name ?: "NO_PRODUCTS"
//프로퍼티 commaDelimitedItemNames
val Order.commaDelimitedItemNames: String
//getter 작성
get() = items.map { it.name }.joinToString() // 3
fun main() {
val order = Order(listOf(Item("Bread", 25.0F), Item("Wine", 29.0F), Item("Water", 12.0F)))
println("Max priced item name: ${order.maxPricedItemName()}") // 4
println("Max priced item value: ${order.maxPricedItemValue()}")
println("Items: ${order.commaDelimitedItemNames}") // 5
}
Item
과 Order
의 단순한 모델을 정의한다. Order
는 Item
객체 컬렉션을 가질 수 있다.Order
타입에 확장 함수를 추가한다.Order
타입에 확장 함수를 추가한다.Order
인스턴스에서 확장 함수를 직접 호출한다.Order
인스턴스에서 확장 프로퍼티에 접근한다.null
참조에서도 확장을 실행할 수 있다. 확장 함수 내에서 객체가 null
인지 체크하고 그 결과를 코드에서 사용할 수 있다:
fun <T> T?.nullSafeToString() = this?.toString() ?: "Null"