函数
概述
函数是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中的数组和集合结构。
下一章: 数组和集合
练习题
- 创建一个计算器类,使用高阶函数实现各种数学运算
- 实现一个文本处理库,包含各种字符串扩展函数
- 编写一个函数式风格的数据验证系统
- 创建一个使用尾递归的树遍历算法
- 设计一个函数组合系统,允许链式调用多个处理函数