Skip to content

函数

概述

函数是Kotlin程序的基本构建块。Kotlin支持函数式编程范式,提供了强大的函数特性,包括高阶函数、lambda表达式、扩展函数等。本章将全面介绍Kotlin中函数的定义、使用和高级特性。

函数基础

基本函数定义

kotlin
// 基本函数语法
fun functionName(parameter1: Type1, parameter2: Type2): ReturnType {
    // 函数体
    return result
}

// 简单函数示例
fun greet(name: String): String {
    return "Hello, $name!"
}

// 无返回值的函数(返回Unit)
fun printMessage(message: String) {
    println(message)
}

// 显式声明Unit返回类型
fun printMessageExplicit(message: String): Unit {
    println(message)
}

fun main() {
    val greeting = greet("Kotlin")
    println(greeting)
    
    printMessage("这是一条消息")
    printMessageExplicit("这是另一条消息")
}

单表达式函数

kotlin
// 单表达式函数
fun add(a: Int, b: Int): Int = a + b

// 类型推断的单表达式函数
fun multiply(a: Int, b: Int) = a * b

// 更复杂的单表达式函数
fun max(a: Int, b: Int) = if (a > b) a else b

// 字符串处理
fun formatName(firstName: String, lastName: String) = "$firstName $lastName"

// 数学计算
fun circleArea(radius: Double) = Math.PI * radius * radius

fun main() {
    println("加法: ${add(5, 3)}")
    println("乘法: ${multiply(4, 6)}")
    println("最大值: ${max(10, 15)}")
    println("格式化姓名: ${formatName("John", "Doe")}")
    println("圆面积: ${"%.2f".format(circleArea(5.0))}")
}

函数参数

默认参数

kotlin
// 带默认参数的函数
fun createUser(
    name: String,
    age: Int = 18,
    email: String = "unknown@example.com",
    isActive: Boolean = true
): String {
    return "User(name=$name, age=$age, email=$email, active=$isActive)"
}

// 多个默认参数
fun connectToDatabase(
    host: String = "localhost",
    port: Int = 5432,
    database: String = "mydb",
    username: String = "user",
    password: String = "password"
): String {
    return "连接到 $host:$port/$database 用户: $username"
}

fun main() {
    // 使用默认参数
    println(createUser("Alice"))
    println(createUser("Bob", 25))
    println(createUser("Charlie", 30, "charlie@example.com"))
    
    // 数据库连接示例
    println(connectToDatabase())
    println(connectToDatabase("remote-server"))
    println(connectToDatabase("remote-server", 3306, "production"))
}

命名参数

kotlin
fun createProduct(
    name: String,
    price: Double,
    category: String,
    inStock: Boolean = true,
    description: String = ""
): String {
    return "Product: $name, Price: $$price, Category: $category, InStock: $inStock"
}

fun main() {
    // 使用命名参数
    val product1 = createProduct(
        name = "笔记本电脑",
        price = 999.99,
        category = "电子产品"
    )
    
    // 改变参数顺序
    val product2 = createProduct(
        category = "书籍",
        name = "Kotlin编程指南",
        price = 49.99,
        description = "学习Kotlin的最佳资源"
    )
    
    // 混合使用位置参数和命名参数
    val product3 = createProduct("手机", 699.99, category = "电子产品", inStock = false)
    
    println(product1)
    println(product2)
    println(product3)
}

可变参数 (vararg)

kotlin
// 可变参数函数
fun sum(vararg numbers: Int): Int {
    var total = 0
    for (number in numbers) {
        total += number
    }
    return total
}

// 可变参数与其他参数结合
fun formatMessage(prefix: String, vararg messages: String, suffix: String = ""): String {
    val combined = messages.joinToString(" ")
    return "$prefix $combined $suffix".trim()
}

// 泛型可变参数
fun <T> printAll(vararg items: T) {
    for (item in items) {
        println(item)
    }
}

fun main() {
    // 使用可变参数
    println("求和: ${sum(1, 2, 3, 4, 5)}")
    println("求和: ${sum(10, 20)}")
    println("求和: ${sum()}")  // 空参数
    
    // 传递数组给可变参数
    val numbers = intArrayOf(1, 2, 3, 4, 5)
    println("数组求和: ${sum(*numbers)}")  // 使用展开操作符
    
    // 格式化消息
    println(formatMessage("错误:", "文件", "未找到", suffix = "!"))
    
    // 泛型可变参数
    printAll("Hello", "World", "Kotlin")
    printAll(1, 2, 3, 4, 5)
}

高阶函数

函数作为参数

kotlin
// 接受函数作为参数的高阶函数
fun calculate(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
    return operation(a, b)
}

// 对列表进行操作的高阶函数
fun processNumbers(numbers: List<Int>, processor: (Int) -> Int): List<Int> {
    return numbers.map(processor)
}

// 条件过滤函数
fun filterItems<T>(items: List<T>, predicate: (T) -> Boolean): List<T> {
    return items.filter(predicate)
}

fun main() {
    // 传递函数作为参数
    val result1 = calculate(10, 5) { a, b -> a + b }
    val result2 = calculate(10, 5) { a, b -> a * b }
    val result3 = calculate(10, 5) { a, b -> a - b }
    
    println("加法: $result1")
    println("乘法: $result2")
    println("减法: $result3")
    
    // 处理数字列表
    val numbers = listOf(1, 2, 3, 4, 5)
    val doubled = processNumbers(numbers) { it * 2 }
    val squared = processNumbers(numbers) { it * it }
    
    println("原始数字: $numbers")
    println("翻倍: $doubled")
    println("平方: $squared")
    
    // 过滤示例
    val words = listOf("apple", "banana", "cherry", "date")
    val longWords = filterItems(words) { it.length > 5 }
    val wordsWithA = filterItems(words) { it.contains('a') }
    
    println("长单词: $longWords")
    println("包含'a'的单词: $wordsWithA")
}

函数作为返回值

kotlin
// 返回函数的函数
fun createMultiplier(factor: Int): (Int) -> Int {
    return { number -> number * factor }
}

// 创建验证器函数
fun createValidator(minLength: Int): (String) -> Boolean {
    return { input -> input.length >= minLength }
}

// 创建格式化器
fun createFormatter(prefix: String, suffix: String): (String) -> String {
    return { content -> "$prefix$content$suffix" }
}

// 函数组合
fun <A, B, C> compose(f: (B) -> C, g: (A) -> B): (A) -> C {
    return { x -> f(g(x)) }
}

fun main() {
    // 使用返回的函数
    val double = createMultiplier(2)
    val triple = createMultiplier(3)
    
    println("2 * 5 = ${double(5)}")
    println("3 * 7 = ${triple(7)}")
    
    // 验证器示例
    val passwordValidator = createValidator(8)
    val usernameValidator = createValidator(3)
    
    println("密码'12345678'有效: ${passwordValidator("12345678")}")
    println("用户名'ab'有效: ${usernameValidator("ab")}")
    
    // 格式化器示例
    val htmlFormatter = createFormatter("<p>", "</p>")
    val markdownFormatter = createFormatter("**", "**")
    
    println(htmlFormatter("Hello World"))
    println(markdownFormatter("Bold Text"))
    
    // 函数组合示例
    val addOne = { x: Int -> x + 1 }
    val multiplyByTwo = { x: Int -> x * 2 }
    val addOneThenDouble = compose(multiplyByTwo, addOne)
    
    println("(5 + 1) * 2 = ${addOneThenDouble(5)}")
}

Lambda 表达式

Lambda 语法

kotlin
fun main() {
    // 基本lambda语法
    val sum = { a: Int, b: Int -> a + b }
    println("Lambda求和: ${sum(3, 4)}")
    
    // 单参数lambda(使用it)
    val square = { x: Int -> x * x }
    val squareIt = { it: Int -> it * it }  // 显式it
    val squareImplicit: (Int) -> Int = { it * it }  // 隐式it
    
    println("平方: ${square(5)}")
    println("平方(it): ${squareIt(6)}")
    println("平方(隐式): ${squareImplicit(7)}")
    
    // 无参数lambda
    val greeting = { "Hello, World!" }
    println(greeting())
    
    // 多行lambda
    val complexOperation = { x: Int, y: Int ->
        val temp = x * 2
        val result = temp + y
        println("中间结果: $temp")
        result  // 最后一行是返回值
    }
    
    println("复杂操作结果: ${complexOperation(5, 3)}")
}

Lambda 与集合操作

kotlin
data class Person(val name: String, val age: Int, val city: String)

fun main() {
    val people = listOf(
        Person("Alice", 25, "New York"),
        Person("Bob", 30, "London"),
        Person("Charlie", 35, "Tokyo"),
        Person("Diana", 28, "Paris"),
        Person("Eve", 32, "Berlin")
    )
    
    // map - 转换
    val names = people.map { it.name }
    val ages = people.map { person -> person.age }
    val nameAgeMap = people.map { "${it.name} (${it.age})" }
    
    println("姓名: $names")
    println("年龄: $ages")
    println("姓名年龄: $nameAgeMap")
    
    // filter - 过滤
    val adults = people.filter { it.age >= 30 }
    val europeans = people.filter { it.city in listOf("London", "Paris", "Berlin") }
    
    println("30岁以上: ${adults.map { it.name }}")
    println("欧洲人: ${europeans.map { it.name }}")
    
    // find - 查找
    val firstAdult = people.find { it.age >= 30 }
    val personInTokyo = people.find { it.city == "Tokyo" }
    
    println("第一个成年人: ${firstAdult?.name}")
    println("东京的人: ${personInTokyo?.name}")
    
    // groupBy - 分组
    val peopleByCity = people.groupBy { it.city }
    val peopleByAgeGroup = people.groupBy { 
        when {
            it.age < 30 -> "年轻"
            it.age < 35 -> "中年"
            else -> "成熟"
        }
    }
    
    println("按城市分组: $peopleByCity")
    println("按年龄组分组: $peopleByAgeGroup")
    
    // sortedBy - 排序
    val sortedByAge = people.sortedBy { it.age }
    val sortedByName = people.sortedBy { it.name }
    
    println("按年龄排序: ${sortedByAge.map { "${it.name}(${it.age})" }}")
    println("按姓名排序: ${sortedByName.map { it.name }}")
}

扩展函数

基本扩展函数

kotlin
// 为String类添加扩展函数
fun String.isPalindrome(): Boolean {
    val cleaned = this.lowercase().replace(" ", "")
    return cleaned == cleaned.reversed()
}

// 为Int类添加扩展函数
fun Int.isEven(): Boolean = this % 2 == 0
fun Int.isOdd(): Boolean = this % 2 != 0
fun Int.factorial(): Long {
    return if (this <= 1) 1 else this * (this - 1).factorial()
}

// 为List添加扩展函数
fun <T> List<T>.secondOrNull(): T? = if (size >= 2) this[1] else null
fun <T> List<T>.penultimate(): T? = if (size >= 2) this[size - 2] else null

// 扩展属性
val String.wordCount: Int
    get() = this.split("\\s+".toRegex()).size

val List<Int>.average: Double
    get() = if (isEmpty()) 0.0 else sum().toDouble() / size

fun main() {
    // 使用字符串扩展函数
    val text1 = "A man a plan a canal Panama"
    val text2 = "Hello World"
    
    println("'$text1' 是回文: ${text1.isPalindrome()}")
    println("'$text2' 是回文: ${text2.isPalindrome()}")
    println("'$text1' 单词数: ${text1.wordCount}")
    
    // 使用整数扩展函数
    val number = 8
    println("$number 是偶数: ${number.isEven()}")
    println("$number 是奇数: ${number.isOdd()}")
    println("$number 的阶乘: ${number.factorial()}")
    
    // 使用列表扩展函数
    val numbers = listOf(1, 2, 3, 4, 5)
    println("列表: $numbers")
    println("第二个元素: ${numbers.secondOrNull()}")
    println("倒数第二个元素: ${numbers.penultimate()}")
    println("平均值: ${numbers.average}")
}

扩展函数的作用域

kotlin
class MathUtils {
    // 类内部的扩展函数
    fun Int.square(): Int = this * this
    
    fun Double.round(decimals: Int): Double {
        val factor = kotlin.math.pow(10.0, decimals.toDouble())
        return kotlin.math.round(this * factor) / factor
    }
    
    fun demonstrateExtensions() {
        println("5的平方: ${5.square()}")
        println("3.14159四舍五入到2位: ${3.14159.round(2)}")
    }
}

// 顶级扩展函数
fun String.toTitleCase(): String {
    return this.split(" ").joinToString(" ") { word ->
        word.lowercase().replaceFirstChar { it.uppercase() }
    }
}

fun main() {
    val mathUtils = MathUtils()
    mathUtils.demonstrateExtensions()
    
    // 顶级扩展函数可以在任何地方使用
    val text = "hello world kotlin"
    println("标题格式: ${text.toTitleCase()}")
}

内联函数

内联函数基础

kotlin
// 内联函数
inline fun measureTime(action: () -> Unit): Long {
    val startTime = System.currentTimeMillis()
    action()
    val endTime = System.currentTimeMillis()
    return endTime - startTime
}

// 带参数的内联函数
inline fun <T> withLogging(name: String, action: () -> T): T {
    println("开始执行: $name")
    val result = action()
    println("完成执行: $name")
    return result
}

// noinline参数
inline fun processData(
    data: List<Int>,
    transform: (Int) -> Int,
    noinline logger: (String) -> Unit
) {
    logger("开始处理数据")
    val result = data.map(transform)
    logger("处理完成,结果: $result")
}

fun main() {
    // 使用内联函数
    val time = measureTime {
        Thread.sleep(100)  // 模拟耗时操作
        println("执行了一些操作")
    }
    println("执行时间: ${time}ms")
    
    // 带返回值的内联函数
    val result = withLogging("数据计算") {
        val numbers = listOf(1, 2, 3, 4, 5)
        numbers.sum()
    }
    println("计算结果: $result")
    
    // 使用noinline参数
    processData(
        data = listOf(1, 2, 3, 4, 5),
        transform = { it * 2 },
        logger = { message -> println("[LOG] $message") }
    )
}

局部函数

嵌套函数

kotlin
fun processUser(name: String, email: String): String {
    // 局部函数
    fun validateName(name: String): Boolean {
        return name.isNotBlank() && name.length >= 2
    }
    
    fun validateEmail(email: String): Boolean {
        return email.contains("@") && email.contains(".")
    }
    
    fun formatResult(name: String, email: String): String {
        return "用户: $name, 邮箱: $email"
    }
    
    // 使用局部函数
    return when {
        !validateName(name) -> "无效的姓名"
        !validateEmail(email) -> "无效的邮箱"
        else -> formatResult(name, email)
    }
}

// 更复杂的局部函数示例
fun calculateStatistics(numbers: List<Double>): Map<String, Double> {
    fun mean(): Double = numbers.sum() / numbers.size
    
    fun variance(): Double {
        val avg = mean()
        return numbers.map { (it - avg) * (it - avg) }.sum() / numbers.size
    }
    
    fun standardDeviation(): Double = kotlin.math.sqrt(variance())
    
    fun median(): Double {
        val sorted = numbers.sorted()
        val size = sorted.size
        return if (size % 2 == 0) {
            (sorted[size / 2 - 1] + sorted[size / 2]) / 2
        } else {
            sorted[size / 2]
        }
    }
    
    return mapOf(
        "mean" to mean(),
        "variance" to variance(),
        "standardDeviation" to standardDeviation(),
        "median" to median(),
        "min" to numbers.minOrNull() ?: 0.0,
        "max" to numbers.maxOrNull() ?: 0.0
    )
}

fun main() {
    // 测试用户处理
    println(processUser("Alice", "alice@example.com"))
    println(processUser("", "invalid-email"))
    println(processUser("Bob", "bob@test.com"))
    
    // 测试统计计算
    val data = listOf(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0)
    val stats = calculateStatistics(data)
    
    println("\n数据统计:")
    stats.forEach { (key, value) ->
        println("$key: ${"%.2f".format(value)}")
    }
}

尾递归函数

tailrec 关键字

kotlin
// 尾递归阶乘
tailrec fun factorial(n: Long, accumulator: Long = 1): Long {
    return if (n <= 1) {
        accumulator
    } else {
        factorial(n - 1, n * accumulator)
    }
}

// 尾递归斐波那契
tailrec fun fibonacci(n: Int, a: Long = 0, b: Long = 1): Long {
    return when (n) {
        0 -> a
        1 -> b
        else -> fibonacci(n - 1, b, a + b)
    }
}

// 尾递归求和
tailrec fun sumList(list: List<Int>, accumulator: Int = 0): Int {
    return if (list.isEmpty()) {
        accumulator
    } else {
        sumList(list.drop(1), accumulator + list.first())
    }
}

// 尾递归查找
tailrec fun findElement<T>(
    list: List<T>, 
    element: T, 
    index: Int = 0
): Int {
    return when {
        index >= list.size -> -1
        list[index] == element -> index
        else -> findElement(list, element, index + 1)
    }
}

fun main() {
    // 测试尾递归函数
    println("10的阶乘: ${factorial(10)}")
    println("20的阶乘: ${factorial(20)}")
    
    println("斐波那契数列:")
    for (i in 0..10) {
        print("${fibonacci(i)} ")
    }
    println()
    
    val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    println("列表求和: ${sumList(numbers)}")
    
    val fruits = listOf("apple", "banana", "cherry", "date")
    println("查找'cherry': ${findElement(fruits, "cherry")}")
    println("查找'grape': ${findElement(fruits, "grape")}")
}

实际应用示例

函数式编程风格的数据处理

kotlin
data class Order(
    val id: String,
    val customerId: String,
    val items: List<OrderItem>,
    val status: OrderStatus
)

data class OrderItem(
    val productId: String,
    val name: String,
    val price: Double,
    val quantity: Int
)

enum class OrderStatus { PENDING, PROCESSING, SHIPPED, DELIVERED, CANCELLED }

class OrderProcessor {
    
    // 高阶函数:订单过滤器
    fun filterOrders(
        orders: List<Order>,
        predicate: (Order) -> Boolean
    ): List<Order> = orders.filter(predicate)
    
    // 计算订单总价
    fun Order.totalAmount(): Double = items.sumOf { it.price * it.quantity }
    
    // 订单统计
    fun generateStatistics(orders: List<Order>): Map<String, Any> {
        val totalOrders = orders.size
        val totalRevenue = orders.sumOf { it.totalAmount() }
        val averageOrderValue = if (totalOrders > 0) totalRevenue / totalOrders else 0.0
        
        val statusCounts = orders.groupingBy { it.status }.eachCount()
        val topCustomers = orders
            .groupBy { it.customerId }
            .mapValues { (_, customerOrders) -> 
                customerOrders.sumOf { it.totalAmount() }
            }
            .toList()
            .sortedByDescending { it.second }
            .take(5)
        
        return mapOf(
            "totalOrders" to totalOrders,
            "totalRevenue" to totalRevenue,
            "averageOrderValue" to averageOrderValue,
            "statusCounts" to statusCounts,
            "topCustomers" to topCustomers
        )
    }
    
    // 订单处理管道
    fun processOrdersPipeline(
        orders: List<Order>,
        filters: List<(Order) -> Boolean> = emptyList(),
        transformations: List<(Order) -> Order> = emptyList()
    ): List<Order> {
        return orders
            .let { orderList ->
                filters.fold(orderList) { acc, filter -> acc.filter(filter) }
            }
            .let { filteredOrders ->
                transformations.fold(filteredOrders) { acc, transform ->
                    acc.map(transform)
                }
            }
    }
}

fun main() {
    val orders = listOf(
        Order("1", "customer1", listOf(
            OrderItem("p1", "笔记本", 999.99, 1),
            OrderItem("p2", "鼠标", 29.99, 2)
        ), OrderStatus.DELIVERED),
        
        Order("2", "customer2", listOf(
            OrderItem("p3", "键盘", 79.99, 1)
        ), OrderStatus.SHIPPED),
        
        Order("3", "customer1", listOf(
            OrderItem("p1", "笔记本", 999.99, 2)
        ), OrderStatus.PROCESSING),
        
        Order("4", "customer3", listOf(
            OrderItem("p4", "显示器", 299.99, 1),
            OrderItem("p2", "鼠标", 29.99, 1)
        ), OrderStatus.PENDING)
    )
    
    val processor = OrderProcessor()
    
    // 使用扩展函数计算总价
    with(processor) {
        orders.forEach { order ->
            println("订单 ${order.id} 总价: ${"%.2f".format(order.totalAmount())}")
        }
    }
    
    // 过滤高价值订单
    val highValueOrders = processor.filterOrders(orders) { 
        with(processor) { it.totalAmount() > 500 }
    }
    println("\n高价值订单: ${highValueOrders.map { it.id }}")
    
    // 生成统计报告
    val stats = processor.generateStatistics(orders)
    println("\n订单统计:")
    stats.forEach { (key, value) ->
        println("$key: $value")
    }
    
    // 使用处理管道
    val processedOrders = processor.processOrdersPipeline(
        orders = orders,
        filters = listOf(
            { it.status != OrderStatus.CANCELLED },
            { with(processor) { it.totalAmount() > 100 } }
        )
    )
    
    println("\n处理后的订单: ${processedOrders.map { it.id }}")
}

最佳实践

1. 函数设计原则

kotlin
// 好的做法:单一职责
fun calculateTax(amount: Double, rate: Double): Double = amount * rate

fun formatCurrency(amount: Double): String = "$%.2f".format(amount)

fun validateEmail(email: String): Boolean = 
    email.contains("@") && email.contains(".")

// 避免:一个函数做太多事情
fun badProcessOrder(order: Order): String {
    // 验证、计算、格式化、发送邮件等多个职责
    // 这样的函数难以测试和维护
    return ""
}

2. 使用适当的函数类型

kotlin
// 对于简单操作,使用单表达式函数
fun isPositive(number: Int) = number > 0

// 对于复杂逻辑,使用完整函数体
fun processComplexData(data: List<String>): Map<String, Int> {
    val result = mutableMapOf<String, Int>()
    
    for (item in data) {
        // 复杂的处理逻辑
        val processed = item.trim().lowercase()
        result[processed] = result.getOrDefault(processed, 0) + 1
    }
    
    return result
}

// 对于重复使用的逻辑,创建扩展函数
fun String.isValidPhoneNumber(): Boolean {
    return this.matches(Regex("\\d{3}-\\d{3}-\\d{4}"))
}

3. 合理使用高阶函数

kotlin
// 好的做法:使用标准库的高阶函数
fun processItems(items: List<String>): List<String> {
    return items
        .filter { it.isNotBlank() }
        .map { it.trim().lowercase() }
        .distinct()
        .sorted()
}

// 创建可复用的高阶函数
fun <T, R> List<T>.mapNotNull(transform: (T) -> R?): List<R> {
    return this.mapNotNull(transform)
}

下一步

掌握了函数的各种特性后,让我们学习Kotlin中的数组和集合结构。

下一章: 数组和集合

练习题

  1. 创建一个计算器类,使用高阶函数实现各种数学运算
  2. 实现一个文本处理库,包含各种字符串扩展函数
  3. 编写一个函数式风格的数据验证系统
  4. 创建一个使用尾递归的树遍历算法
  5. 设计一个函数组合系统,允许链式调用多个处理函数

本站内容仅供学习和研究使用。