오늘은 코틀린의 고차함수를 배워보겠습니다.
fun <T> filter(list: List<T>, predicate: (T) -> Boolean): List<T> {
val result = mutableListOf<T>()
for (item in list) {
if (predicate(item)) {
result.add(item)
}
}
return result
}
// 함수 리터럴의 예: 람다 표현식
val isEven = { x: Int -> x % 2 == 0 }
// 사용 예시
val numbers = listOf(1, 2, 3, 4, 5, 6)
val evenNumbers = filter(numbers, isEven)
println(evenNumbers) // 출력: [2, 4, 6]
// 복잡한 함수 타입의 예: 함수를 반환하는 함수
fun operation(): (Int, Int) -> Int {
return { a, b -> a + b }
}
// 고차 함수의 단점 예시: 함수 타입이 복잡해질 수 있음
fun calculate(a: Int, b: Int, op: (Int, Int) -> Int): Int {
return op(a, b)
}
val sum = calculate(5, 3, operation())
println(sum) // 출력: 8
// 이 경우 함수 타입 (Int, Int) -> Int를 여러 번 사용하므로 코드가 장황해질 수 있습니다.
// inline 함수의 예
inline fun <T> lock(lock: Lock, body: () -> T): T {
lock.lock()
try {
return body()
} finally {
lock.unlock()
}
}
// 사용 예시
val lock = ReentrantLock()
lock(lock) {
println("Locked and executing!")
}
예를 들어, 자바의 Runnable 인터페이스는 단일 추상 메서드 run()을 가지고 있습니다.
코틀린에서는 이를 람다로 사용할 수 있습니다.
예시
fun runRunnable(runnable: Runnable) {
runnable.run()
}
fun main() {
// SAM 변환을 사용한 람다 표현식
runRunnable { println("Hello from a Runnable") }
}
runRunnable 함수는 Runnable 타입의 매개변수를 받습니다. 이를 호출할 때 람다 표현식을 사용하여 Runnable의 run 메서드를 구현할 수 있습니다.
함수 참조는 코틀린에서 함수 또는 메서드를 변수에 저장하거나 다른 함수에 전달할 수 있는 기능입니다. 함수 참조는 :: 연산자를 사용하여 생성됩니다.
아래 예제들에서 함수 참조는 함수 또는 메서드를 :: 연산자를 사용하여 변수에 할당하거나 다른 함수에 전달합니다.
fun greet(name: String) {
println("Hello, $name!")
}
fun main() {
val greeter: (String) -> Unit = ::greet
greeter("World")
}
class Person(val name: String) {
fun sayHello() {
println("Hello, my name is $name")
}
}
fun main() {
val person = Person("Alice")
val greeter: () -> Unit = person::sayHello
greeter()
}
fun String.shout() {
println(this.uppercase())
}
fun main() {
val shouter: String.() -> Unit = String::shout
"hello".shouter()
}
class User(val name: String, val age: Int)
fun main() {
val userCreator: (String, Int) -> User = ::User
val user = userCreator("Bob", 30)
println("${user.name}, ${user.age}")
}
fun main() {
val list = listOf("banana", "apple", "cherry")
// 람다 표현식 사용
list.sortedWith(Comparator { a, b -> a.length - b.length }).forEach { println(it) }
// 함수 참조 사용
val compareByLength: (String, String) -> Int = { a, b -> a.length - b.length }
list.sortedWith(Comparator(compareByLength)).forEach { println(it) }
}
결국엔 코드의 재사용성과 가독성을 높이기 위해 즉, 성능을 위해 사용하는 것으로 문법이 익숙해지면 클린 코드 작성에 용이할 것으로 보인다 !