반응형
이번엔 함수형 프로그래밍을 코틀린에서 어떻게 사용할 수 있는지 알아보겠습니다.
고차 함수 (Higher-Order Functions)
고차 함수는 다른 함수를 매개변수로 취하거나 함수를 반환하는 함수입니다.
일급 객체란?
Kotlin 함수는 일급 객체(First-class citizen)입니다. 아래 3가지 조건을 충족한다면 1급 객체라고 할 수 있습니다.
- 변수나 데이터에 할당할 수 있어야 한다.
- 객체의 인자로 넘길 수 있어야 한다.
- 객체의 리턴값으로 반환할 수 있어야 한다.
함수를 매개변수로 사용하기
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 signature와 일치하는 함수를 선언합니다.
- 두 개의 정수 값과 함수 인자 ::sum을 전달하는 고차 함수를 호출합니다. ::는 Kotlin에서 이름으로 함수를 참조하는 표기법입니다.
- 람다를 함수 인자로 전달하는 고차 함수를 호출합니다.
함수를 반환 값으로 사용하기
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 함수의 매개변수와 반환 유형을 나타냅니다.
- 파라미터, 반환형이 일치하는 함수를 선언합니다.
- 변수에 할당된 결과를 가져오는 작업을 호출합니다. 여기서 func는 연산에 의해 반환되는 제곱이 됩니다.
- square 함수가 실제로 실행됩니다.
람다 함수(Lambda Functions)
Lambda 함수("lambdas")는 임시로 함수를 생성하는 간단한 방법입니다. 타입 추론과 암시적 it 변수 덕분에 많은 경우에 람다를 매우 간결하게 표시할 수 있습니다.
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 변수를 사용할 수 있습니다. 이는 유형을 추론할 수 있는 경우에 특히 유용합니다
- 람다가 단일 함수 호출로 구성된 경우 함수 포인터(::)를 사용할 수 있습니다.
확장 함수와 프로퍼티 (Extension Functions and Properties)
Kotlin을 사용하면 확장 메커니즘을 사용하여 모든 클래스에 새 멤버를 추가할 수 있습니다. 즉, 확장 함수와 확장 프로퍼티의 두 가지 유형이 있습니다. 일반 함수 및 프로퍼티와 매우 유사해 보이지만 한 가지 중요한 차이점이 있는데 그것은 확장할 유형을 지정해야 한다는 것입니다.
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"
val Order.commaDelimitedItemNames: String // 3
get() = items.map { it.name }.joinToString()
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
// Max priced item value: 29.0
println("Max priced item value: ${order.maxPricedItemValue()}")
// Items: Bread, Wine, Water
println("Items: ${order.commaDelimitedItemNames}") // 5
}
- Item 및 Order의 간단한 모델을 정의합니다. Order에는 Item 객체 컬렉션이 포함됩니다.
- Order 타입에 대한 확장 함수를 추가합니다.
- Order 타입에 대한 확장 프로퍼티를 추가합니다.
- Order의 인스턴스에서 직접 확장 함수를 호출합니다.
- Order 인스턴스의 확장 속성에 접근합니다.
null 참조에서 확장을 실행하는 것도 가능합니다. 확장 함수에서 개체에 null이 있는지 확인하고 코드에서 결과를 사용할 수 있습니다.
fun <T> T?.nullSafeToString() = this?.toString() ?: "NULL" // 1
반응형
'Language > Kotlin' 카테고리의 다른 글
코틀린[Kotlin] Collections에서 자주 사용하는 함수 알아보기 (Filter, map, count, groupby ....) (0) | 2021.09.24 |
---|---|
코틀린[Kotlin] 컬렉션(Collections) 알아보기 (List, Map, Set ...) (0) | 2021.09.24 |
코틀린[Kotlin] 특별한 클래스들 (Data, Enum, Sealed Classes And Object) (0) | 2021.09.22 |
코틀린[Kotlin] 흐름 통제하기 (When, Loop, Ranges, Equality, Contidional ..) (0) | 2021.09.22 |
코틀린[Kotlin] 기본 문법 2 (클래스, 제너릭, 상속) (0) | 2021.09.22 |