Higher-Order Functions trong Kotlin
1. Giới thiệu
Higher-order functions là functions nhận function khác làm parameter hoặc trả về function.
2. Function làm Parameter
fun operate(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
return operation(a, b)
}
fun main() {
val sum = operate(5, 3) { x, y -> x + y }
val product = operate(5, 3) { x, y -> x * y }
println(sum) // 8
println(product) // 15
}3. Function trả về Function
fun multiplier(factor: Int): (Int) -> Int {
return { number -> number * factor }
}
fun main() {
val double = multiplier(2)
val triple = multiplier(3)
println(double(5)) // 10
println(triple(5)) // 15
}4. Function Types
// No params, returns Unit
val action: () -> Unit = { println("Action!") }
// One param, returns Int
val square: (Int) -> Int = { it * it }
// Two params, returns Boolean
val compare: (Int, Int) -> Boolean = { a, b -> a > b }
// Nullable function type
val nullable: ((Int) -> Int)? = null5. Built-in Higher-Order Functions
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
// map
println(numbers.map { it * 2 })
// filter
println(numbers.filter { it > 2 })
// reduce
println(numbers.reduce { acc, n -> acc + n })
// fold
println(numbers.fold(10) { acc, n -> acc + n })
// groupBy
println(numbers.groupBy { if (it % 2 == 0) "even" else "odd" })
}6. Function References
fun isEven(n: Int) = n % 2 == 0
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
// Function reference với ::
val evens = numbers.filter(::isEven)
println(evens) // [2, 4]
// Method reference
val strings = listOf("a", "bc", "def")
val lengths = strings.map(String::length)
println(lengths) // [1, 2, 3]
}7. Inline Functions
inline fun measureTime(action: () -> Unit): Long {
val start = System.currentTimeMillis()
action()
return System.currentTimeMillis() - start
}
fun main() {
val time = measureTime {
Thread.sleep(100)
}
println("Took $time ms")
}8. crossinline và noinline
inline fun inlineExample(
noinline notInlined: () -> Unit,
crossinline crosslined: () -> Unit
) {
// noinline: không inline, có thể lưu vào biến
val stored = notInlined
// crossinline: inline nhưng không cho phép non-local return
val runnable = Runnable { crosslined() }
}9. Tạo DSL với Higher-Order Functions
class HtmlBuilder {
private val content = StringBuilder()
fun tag(name: String, block: HtmlBuilder.() -> Unit) {
content.append("<$name>")
this.block()
content.append("</$name>")
}
fun text(value: String) {
content.append(value)
}
override fun toString() = content.toString()
}
fun html(block: HtmlBuilder.() -> Unit): String {
val builder = HtmlBuilder()
builder.block()
return builder.toString()
}
fun main() {
val result = html {
tag("html") {
tag("body") {
text("Hello, World!")
}
}
}
println(result)
}10. Ví dụ thực tế
// Retry pattern
inline fun <T> retry(times: Int, block: () -> T): T {
var lastException: Exception? = null
repeat(times) {
try {
return block()
} catch (e: Exception) {
lastException = e
}
}
throw lastException!!
}
fun main() {
val result = retry(3) {
// Có thể fail
fetchData()
}
}📝 Tóm tắt
- Higher-order = nhận hoặc trả về function
- Function type:
(params) -> returnType ::cho function/method referencesinlinetránh overhead của lambdanoinline,crossinlinecho special cases- Nền tảng cho DSLs và functional programming
Last updated on