Kotlin 语言函数类型操作
Kotlin 中的函数是一等公民,函数类型是其函数式编程能力的核心。让我们深入了解函数类型的操作。
1. 函数类型基础
函数类型声明
kotlin
// 1. 基本函数类型
val greet: (String) -> String = { name -> "Hello, $name!" }
// 2. 带接收者的函数类型
val stringBuilderAction: StringBuilder.() -> Unit = {
append("Hello")
append(" World")
}
// 3. 可空函数类型
var callback: ((Int) -> String)? = null
// 4. 多参数函数类型
val calculate: (Int, Int, Int) -> Int = { a, b, c -> a + b + c }
// 5. 返回函数的函数类型
val createAdder: (Int) -> (Int) -> Int = { x -> { y -> x + y } }
类型别名使代码更清晰
kotlin
// 定义函数类型别名
typealias StringTransformer = (String) -> String
typealias Predicate<T> = (T) -> Boolean
typealias EventHandler<T> = (T) -> Unit
typealias AsyncOperation = (callback: (Result<String>) -> Unit) -> Unit
// 使用类型别名
val upperCase: StringTransformer = { it.uppercase() }
val isEven: Predicate<Int> = { it % 2 == 0 }
val onSuccess: EventHandler<String> = { println("成功: $it") }
// 复杂嵌套类型
typealias DatabaseQuery<T> = (connection: Connection) -> List<T>
typealias ValidationRule<T> = (T) -> ValidationResult
2. 函数类型的操作
调用函数类型
kotlin
// 直接调用
val sum: (Int, Int) -> Int = { a, b -> a + b }
val result1 = sum(10, 20) // 直接调用
val result2 = sum.invoke(10, 20) // 使用 invoke 方法
// 安全调用可空函数类型
var operation: ((Int) -> Int)? = null
val result3 = operation?.invoke(5) // 安全调用,结果为 null
val result4 = operation?.let { it(5) } // 使用 let
// 带接收者的调用
val buildString: StringBuilder.() -> Unit = {
append("构建的字符串")
}
val builder = StringBuilder()
builder.buildString() // 在接收者上调用
println(builder.toString())
函数组合
kotlin
// 1. 组合函数(数学上的组合:f(g(x)))
infix fun <A, B, C> ((B) -> C).compose(g: (A) -> B): (A) -> C {
return { a -> this(g(a)) }
}
infix fun <A, B, C> ((A) -> B).andThen(f: (B) -> C): (A) -> C {
return { a -> f(this(a)) }
}
// 使用示例
val addTwo: (Int) -> Int = { it + 2 }
val multiplyByThree: (Int) -> Int = { it * 3 }
val square: (Int) -> Int = { it * it }
// 组合:先加2,然后乘以3,然后平方
val composed = addTwo andThen multiplyByThree andThen square
println(composed(5)) // (5+2)*3 = 21, 21² = 441
// 另一种顺序:先平方,然后加2,然后乘以3
val composed2 = square compose addTwo andThen multiplyByThree
println(composed2(5)) // 5²=25, 25+2=27, 27*3=81
// 2. 管道操作(Unix 风格)
infix fun <T, R> T.pipe(f: (T) -> R): R = f(this)
val process = 5 pipe addTwo pipe multiplyByThree pipe square
println(process) // 441
柯里化(Currying)
kotlin
// 柯里化:将多参数函数转换为一系列单参数函数
fun <A, B, C> curry(f: (A, B) -> C): (A) -> (B) -> C {
return { a -> { b -> f(a, b) } }
}
fun <A, B, C, D> curry(f: (A, B, C) -> D): (A) -> (B) -> (C) -> D {
return { a -> { b -> { c -> f(a, b, c) } } }
}
// 反柯里化
fun <A, B, C> uncurry(f: (A) -> (B) -> C): (A, B) -> C {
return { a, b -> f(a)(b) }
}
// 使用示例
val add: (Int, Int) -> Int = { a, b -> a + b }
val curriedAdd = curry(add)
val addFive = curriedAdd(5) // (Int) -> Int
println(addFive(3)) // 8
// 部分应用
fun <A, B, C> partial1(f: (A, B) -> C, a: A): (B) -> C {
return { b -> f(a, b) }
}
fun <A, B, C> partial2(f: (A, B) -> C, b: B): (A) -> C {
return { a -> f(a, b) }
}
// 使用部分应用
val multiply: (Int, Int) -> Int = { a, b -> a * b }
val double = partial1(multiply, 2) // 乘以2的函数
val triple = partial2(multiply, 3) // 乘以3的函数
println(double(5)) // 10
println(triple(4)) // 12
3. 高阶函数操作
函数作为参数
kotlin
// 接收函数作为参数的函数
fun <T> List<T>.customFilter(predicate: (T) -> Boolean): List<T> {
val result = mutableListOf<T>()
for (item in this) {
if (predicate(item)) {
result.add(item)
}
}
return result
}
// 使用
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val evens = numbers.customFilter { it % 2 == 0 }
val bigNumbers = numbers.customFilter { it > 5 }
// 多个函数参数
fun <T, R> transformList(
list: List<T>,
filter: (T) -> Boolean,
mapper: (T) -> R
): List<R> {
return list.filter(filter).map(mapper)
}
val result = transformList(
list = numbers,
filter = { it > 3 },
mapper = { it * 2 }
)
函数作为返回值
kotlin
// 返回函数的函数
fun createCounter(start: Int = 0): () -> Int {
var count = start
return { count++ }
}
// 使用
val counter1 = createCounter()
val counter2 = createCounter(100)
println(counter1()) // 0
println(counter1()) // 1
println(counter2()) // 100
println(counter2()) // 101
// 配置生成器模式
fun createLogger(level: String): (String) -> Unit {
return when (level) {
"DEBUG" -> { message -> println("[DEBUG] $message") }
"INFO" -> { message -> println("[INFO] $message") }
"ERROR" -> { message -> System.err.println("[ERROR] $message") }
else -> { message -> println("[$level] $message") }
}
}
val debugLogger = createLogger("DEBUG")
val errorLogger = createLogger("ERROR")
debugLogger("程序启动")
errorLogger("发生错误")
4. 函数类型的转换
函数适配器
kotlin
// 1. 参数适配
fun <A, B, R> adapt(f: (A, B) -> R): (B, A) -> R {
return { b, a -> f(a, b) }
}
// 使用:交换参数顺序
val divide: (Int, Int) -> Int = { a, b -> a / b }
val divideReversed = adapt(divide)
println(divide(10, 2)) // 5
println(divideReversed(2, 10)) // 5 (2, 10) -> (10, 2) -> 5
// 2. 忽略参数
fun <A, R> ignoreArgument(f: () -> R): (A) -> R {
return { _ -> f() }
}
val getRandom: () -> Int = { (1..100).random() }
val getRandomIgnoringArg = ignoreArgument(getRandom)
println(getRandomIgnoringArg("忽略这个参数")) // 输出随机数
// 3. 柯里化转换器
class FunctionAdapter {
companion object {
// 将 (A, B) -> R 转换为 (A) -> (B) -> R
fun <A, B, R> curry2(f: (A, B) -> R): (A) -> (B) -> R = { a -> { b -> f(a, b) } }
// 将 (A, B, C) -> R 转换为 (A) -> (B) -> (C) -> R
fun <A, B, C, R> curry3(f: (A, B, C) -> R): (A) -> (B) -> (C) -> R =
{ a -> { b -> { c -> f(a, b, c) } } }
// 翻转参数
fun <A, B, R> flip(f: (A, B) -> R): (B, A) -> R = { b, a -> f(a, b) }
// 部分应用
fun <A, B, R> partial(f: (A, B) -> R, a: A): (B) -> R = { b -> f(a, b) }
// 组合函数(左右两种)
fun <A, B, C> compose(f: (B) -> C, g: (A) -> B): (A) -> C = { a -> f(g(a)) }
fun <A, B, C> andThen(f: (A) -> B, g: (B) -> C): (A) -> C = { a -> g(f(a)) }
}
}
函数记忆化(Memoization)
kotlin
// 记忆化:缓存函数结果
fun <T, R> memoize(f: (T) -> R): (T) -> R {
val cache = mutableMapOf<T, R>()
return { input ->
cache.getOrPut(input) { f(input) }
}
}
// 使用:昂贵的计算
val expensiveComputation: (Int) -> Int = { n ->
println("计算 $n 的平方")
Thread.sleep(1000) // 模拟耗时计算
n * n
}
val memoizedSquare = memoize(expensiveComputation)
println(memoizedSquare(5)) // 第一次计算,耗时
println(memoizedSquare(5)) // 第二次,从缓存获取,快速
println(memoizedSquare(10)) // 第一次计算10
println(memoizedSquare(10)) // 第二次,从缓存获取
// 多参数记忆化
fun <A, B, R> memoize2(f: (A, B) -> R): (A, B) -> R {
val cache = mutableMapOf<Pair<A, B>, R>()
return { a, b ->
val key = a to b
cache.getOrPut(key) { f(a, b) }
}
}
5. 标准库中的函数操作
run, let, apply, also, with
kotlin
// 这些标准函数本质上都是对函数类型的操作
class Person(var name: String = "", var age: Int = 0, var city: String = "")
// 1. run: 在对象上执行代码块,返回最后一行
val person = Person().run {
name = "Alice"
age = 30
city = "New York"
"创建完成" // 返回值
}
// 2. let: 对对象执行操作,返回操作结果
val formatted = Person("Bob", 25).let {
"${it.name} (${it.age}岁)"
}
// 3. apply: 配置对象,返回对象本身
val configuredPerson = Person().apply {
name = "Charlie"
age = 35
city = "London"
}
// 4. also: 执行额外操作,返回对象本身
val loggedPerson = Person("David", 40).also {
println("创建了 ${it.name}")
}
// 5. with: 在对象上下文中执行代码块
with(configuredPerson) {
println("$name 住在 $city")
}
takeIf 和 takeUnless
kotlin
// 条件性操作
val number = 42
// takeIf: 如果条件为真,返回对象,否则返回null
val evenNumber = number.takeIf { it % 2 == 0 } // 42
val oddNumber = number.takeIf { it % 2 != 0 } // null
// takeUnless: 如果条件为假,返回对象,否则返回null
val notTen = number.takeUnless { it == 10 } // 42
val isTen = number.takeUnless { it != 10 } // null
// 链式使用
val result = number
.takeIf { it > 0 }
?.takeIf { it < 100 }
?.let { it * 2 }
6. 函数类型的扩展
为函数类型添加扩展函数
kotlin
// 为函数类型定义扩展函数
fun <T, R> ((T) -> R).composeWithLogging(tag: String): (T) -> R {
return { input ->
println("[$tag] 输入: $input")
val result = this(input)
println("[$tag] 输出: $result")
result
}
}
// 为带接收者的函数类型定义扩展
fun <T> T.runWithMeasure(block: T.() -> Unit): Long {
val start = System.currentTimeMillis()
block()
return System.currentTimeMillis() - start
}
// 使用
val addWithLog = { a: Int, b: Int -> a + b }
.curry() // 假设有 curry 扩展
.composeWithLogging("加法")
val result = addWithLog(5)(3)
// 测量执行时间
val time = StringBuilder().runWithMeasure {
append("Hello")
append(" ")
append("World")
}
println("构建字符串耗时: ${time}ms")
函数管道操作符
kotlin
// 自定义管道操作符
infix fun <T, R> T.pipe(f: T.() -> R): R = f()
infix fun <T, R> T.pipeTo(f: (T) -> R): R = f(this)
// 链式管道操作
val processed = "hello world"
.pipe { uppercase() }
.pipe { replace(" ", "_") }
.pipe { "prefix_$this" }
println(processed) // "prefix_HELLO_WORLD"
// 另一种风格
val processed2 = "hello world"
pipeTo { it.uppercase() }
pipeTo { it.replace(" ", "_") }
pipeTo { "prefix_$it" }
7. 函数类型的实际应用
策略模式
kotlin
// 使用函数类型实现策略模式
class PaymentProcessor {
private var paymentStrategy: (Double) -> String = { amount ->
"现金支付: $$amount"
}
fun setStrategy(strategy: (Double) -> String) {
paymentStrategy = strategy
}
fun processPayment(amount: Double): String {
return paymentStrategy(amount)
}
}
// 定义不同的支付策略
val creditCardStrategy = { amount: Double ->
"信用卡支付: $$amount (手续费: $${amount * 0.02})"
}
val paypalStrategy = { amount: Double ->
"PayPal支付: $$amount (手续费: $${amount * 0.01})"
}
val cryptoStrategy = { amount: Double ->
"加密货币支付: $$amount (无手续费)"
}
// 使用
val processor = PaymentProcessor()
processor.setStrategy(creditCardStrategy)
println(processor.processPayment(100.0)) // 信用卡支付
processor.setStrategy(cryptoStrategy)
println(processor.processPayment(100.0)) // 加密货币支付
中间件/拦截器模式
kotlin
// 使用函数类型实现中间件
typealias Middleware<T> = (T, (T) -> T) -> T
class MiddlewarePipeline<T> {
private val middlewares = mutableListOf<Middleware<T>>()
fun use(middleware: Middleware<T>) {
middlewares.add(middleware)
}
fun execute(input: T): T {
// 构建执行链
val chain = middlewares.foldRight({ x: T -> x }) { middleware, next ->
{ input -> middleware(input, next) }
}
return chain(input)
}
}
// 示例:HTTP 请求处理
data class HttpRequest(val path: String, val headers: Map<String, String>)
data class HttpResponse(val status: Int, val body: String)
// 定义中间件
val loggingMiddleware: Middleware<HttpRequest> = { request, next ->
println("请求: ${request.path}")
val response = next(request)
println("响应: ${response.status}")
response
}
val authMiddleware: Middleware<HttpRequest> = { request, next ->
val token = request.headers["Authorization"]
if (token != null && token.startsWith("Bearer ")) {
next(request)
} else {
HttpResponse(401, "未授权")
}
}
val routingMiddleware: Middleware<HttpRequest> = { request, _ ->
when (request.path) {
"/api/users" -> HttpResponse(200, "用户列表")
"/api/products" -> HttpResponse(200, "产品列表")
else -> HttpResponse(404, "未找到")
}
}
// 使用中间件管道
val pipeline = MiddlewarePipeline<HttpRequest>()
pipeline.use(loggingMiddleware)
pipeline.use(authMiddleware)
pipeline.use(routingMiddleware)
val request = HttpRequest("/api/users", mapOf("Authorization" to "Bearer token123"))
val response = pipeline.execute(request)
println(response)
事件处理系统
kotlin
// 使用函数类型构建事件系统
class EventBus {
private val handlers = mutableMapOf<String, MutableList<(Any) -> Unit>>()
fun <T : Any> subscribe(eventType: String, handler: (T) -> Unit) {
val typedHandler = handler as (Any) -> Unit
handlers.getOrPut(eventType) { mutableListOf() }.add(typedHandler)
}
fun <T : Any> publish(eventType: String, event: T) {
handlers[eventType]?.forEach { handler ->
try {
handler(event)
} catch (e: Exception) {
println("事件处理器错误: ${e.message}")
}
}
}
fun <T : Any> unsubscribe(eventType: String, handler: (T) -> Unit) {
val typedHandler = handler as (Any) -> Unit
handlers[eventType]?.remove(typedHandler)
}
}
// 使用事件总线
data class UserRegisteredEvent(val userId: String, val email: String)
data class OrderPlacedEvent(val orderId: String, val amount: Double)
val eventBus = EventBus()
// 订阅事件
eventBus.subscribe<UserRegisteredEvent>("user.registered") { event ->
println("用户注册: ${event.userId}")
// 发送欢迎邮件
}
eventBus.subscribe<OrderPlacedEvent>("order.placed") { event ->
println("订单创建: ${event.orderId}, 金额: $${event.amount}")
// 处理订单逻辑
}
// 发布事件
eventBus.publish("user.registered", UserRegisteredEvent("123", "alice@example.com"))
eventBus.publish("order.placed", OrderPlacedEvent("ORD-456", 99.99))
8. 函数类型与泛型
泛型函数类型
kotlin
// 泛型函数类型
class FunctionContainer<T, R> {
private var function: (T) -> R? = { null }
fun setFunction(f: (T) -> R) {
function = f
}
fun execute(input: T): R? {
return function(input)
}
}
// 高阶泛型函数
fun <T, R> List<T>.mapWithIndexCustom(
transform: (index: Int, T) -> R
): List<R> {
return this.mapIndexed(transform)
}
fun <T> List<T>.filterAndMap(
predicate: (T) -> Boolean,
transform: (T) -> String
): List<String> {
return this.filter(predicate).map(transform)
}
// 约束泛型函数类型
fun <T : Comparable<T>> List<T>.customMax(
comparator: (T, T) -> Int = { a, b -> a.compareTo(b) }
): T? {
return this.maxWithOrNull(comparator)
}
9. 性能考虑
内联函数优化
kotlin
// 使用 inline 减少函数对象开销
inline fun <T> List<T>.filterInline(
predicate: (T) -> Boolean
): List<T> {
val result = mutableListOf<T>()
for (item in this) {
if (predicate(item)) {
result.add(item)
}
}
return result
}
// 但注意:内联大函数会导致代码膨胀
inline fun <T, R> List<T>.mapInline(
transform: (T) -> R
): List<R> {
val result = ArrayList<R>(this.size)
for (item in this) {
result.add(transform(item))
}
return result
}
// 部分内联:只内联 lambda,不内联整个函数
inline fun <T> List<T>.forEachInline(
crossinline action: (T) -> Unit
) {
for (element in this) {
action(element)
}
}
避免创建不必要的函数对象
kotlin
// 不好的做法:每次调用都创建新的函数
fun createProcessor(): (String) -> String {
return { input -> input.uppercase() } // 每次都创建新的 lambda
}
// 好的做法:重用函数对象
val uppercaseFunction = { input: String -> input.uppercase() }
fun createProcessorBetter(): (String) -> String {
return uppercaseFunction // 重用同一个函数对象
}
// 使用函数引用而不是 lambda
val list = listOf("a", "b", "c")
val result1 = list.map { it.uppercase() } // 创建 lambda
val result2 = list.map(String::uppercase) // 使用函数引用(更高效)
总结
Kotlin 的函数类型操作提供了强大的函数式编程能力:
核心概念:
- 函数作为一等公民:可以像其他值一样传递、返回和操作
- 函数类型语法 :
(参数类型) -> 返回类型 - 高阶函数:接收或返回函数的函数
- Lambda 表达式:简洁的函数字面量
高级操作:
- 函数组合 :
compose、andThen - 柯里化:多参数函数转换为单参数函数序列
- 部分应用:固定部分参数创建新函数
- 函数适配:修改函数签名
设计模式应用:
- 策略模式:使用函数类型替换策略接口
- 装饰器模式:通过函数组合增强功能
- 观察者模式:使用函数类型作为事件处理器
- 中间件模式:函数链式处理
性能优化:
- 内联函数:减少函数调用开销
- 函数引用:比 lambda 更高效
- 函数记忆化:缓存计算结果
- 避免重复创建:重用函数对象
函数类型操作让 Kotlin 代码更加简洁、灵活和表达力强,是现代 Kotlin 编程中不可或缺的一部分。