2-2-44 快速掌握Kotlin-函数类型操作

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")
}

takeIftakeUnless

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 的函数类型操作提供了强大的函数式编程能力:

核心概念:

  1. 函数作为一等公民:可以像其他值一样传递、返回和操作
  2. 函数类型语法(参数类型) -> 返回类型
  3. 高阶函数:接收或返回函数的函数
  4. Lambda 表达式:简洁的函数字面量

高级操作:

  1. 函数组合composeandThen
  2. 柯里化:多参数函数转换为单参数函数序列
  3. 部分应用:固定部分参数创建新函数
  4. 函数适配:修改函数签名

设计模式应用:

  1. 策略模式:使用函数类型替换策略接口
  2. 装饰器模式:通过函数组合增强功能
  3. 观察者模式:使用函数类型作为事件处理器
  4. 中间件模式:函数链式处理

性能优化:

  1. 内联函数:减少函数调用开销
  2. 函数引用:比 lambda 更高效
  3. 函数记忆化:缓存计算结果
  4. 避免重复创建:重用函数对象

函数类型操作让 Kotlin 代码更加简洁、灵活和表达力强,是现代 Kotlin 编程中不可或缺的一部分。

相关推荐
有位神秘人2 小时前
Android中获取设备里面的音频文件
android
2501_915918413 小时前
使用 HBuilder 上架 iOS 应用时常见的问题与应对方式
android·ios·小程序·https·uni-app·iphone·webview
farewell-Calm4 小时前
01_Android快速入门
android
helloCat4 小时前
记录CI/CD自动化上传AppGallery遇到的坑
android·前端·api
WordPress学习笔记5 小时前
wordpress根据页面别名获取该页面的链接
android·wordpress
2501_916007475 小时前
iOS 崩溃日志的分析方法,将崩溃日志与运行过程结合分析
android·ios·小程序·https·uni-app·iphone·webview
浅箬5 小时前
Taro3的H5项目在Android、IOS 中因为兼容性问题导致的白屏问题
android·团队开发·taro
技术摆渡人5 小时前
Android 全栈架构终极指南:从 Linux 内核、Binder 驱动到 Framework 源码实战
android·linux·架构
00后程序员张6 小时前
苹果应用商店上架App流程,签名证书、IPA 校验、上传
android·ios·小程序·https·uni-app·iphone·webview