Kotlin 语言函数类别详解
Kotlin 提供了丰富多样的函数类型,每种类型都有其特定的用途和语法特点。以下是 Kotlin 中主要函数类别的全面解析:
一、按声明位置分类
1. 顶层函数 (Top-Level Functions)
直接定义在文件中,不属于任何类
// 在文件中直接定义
fun greet(name: String): String {
return "Hello, $name!"
}
// 可直接调用
fun main() {
println(greet("Alice")) // 无需类名
}
2. 成员函数 (Member Functions)
定义在类或接口内部
class Calculator {
// 成员函数
fun add(a: Int, b: Int): Int {
return a + b
}
// 带默认参数的成员函数
fun multiply(a: Int = 1, b: Int = 1): Int = a * b
}
fun main() {
val calc = Calculator()
println(calc.add(5, 3)) // 8
println(calc.multiply(4, 2)) // 8
}
3. 局部函数 (Local Functions)
在函数内部定义的函数
fun processText(text: String): String {
// 局部函数,可以访问外部函数的参数和变量
fun validate(input: String): Boolean {
return input.isNotBlank() && input.length > 2
}
fun format(input: String): String {
return input.trim().uppercase()
}
return if (validate(text)) format(text) else "INVALID"
}
fun main() {
println(processText(" hello ")) // HELLO
println(processText("a")) // INVALID
}
二、按行为特性分类
1. 扩展函数 (Extension Functions)
为现有类添加新功能
// 为 String 类添加扩展函数
fun String.addExclamation(): String = "$this!"
// 为 List<Int> 添加扩展函数
fun List<Int>.averageValue(): Double {
return if (isEmpty()) 0.0 else sum().toDouble() / size
}
// 为可空类型添加扩展函数
fun String?.safeLength(): Int = this?.length ?: 0
fun main() {
val greeting = "Hello"
println(greeting.addExclamation()) // Hello!
val numbers = listOf(1, 2, 3, 4, 5)
println(numbers.averageValue()) // 3.0
val nullableString: String? = null
println(nullableString.safeLength()) // 0
}
2. 中缀函数 (Infix Functions)
使用中缀表示法调用
infix fun Int.pow(exponent: Int): Int {
return Math.pow(this.toDouble(), exponent.toDouble()).toInt()
}
infix fun String.repeat(times: Int): String {
return this.repeat(times)
}
class Person(val name: String) {
infix fun marry(spouse: Person) {
println("$name 和 ${spouse.name} 结婚了")
}
}
fun main() {
println(2 pow 3) // 8
println("ha" repeat 3) // hahaha
val alice = Person("Alice")
val bob = Person("Bob")
alice marry bob // Alice 和 Bob 结婚了
}
3. 内联函数 (Inline Functions)
将函数体直接插入调用处
// 普通高阶函数(会有 lambda 对象创建开销)
fun normalHigherOrder(block: () -> Unit) {
println("开始执行")
block()
println("执行结束")
}
// 内联函数(消除 lambda 开销)
inline fun inlineHigherOrder(block: () -> Unit) {
println("开始执行")
block()
println("执行结束")
}
// 带具体化类型参数的内联函数
inline fun <reified T> checkType(value: Any) {
if (value is T) {
println("$value 是 ${T::class.simpleName} 类型")
} else {
println("$value 不是 ${T::class.simpleName} 类型")
}
}
fun main() {
// 编译后,inlineHigherOrder 的代码会被直接插入这里
inlineHigherOrder {
println("执行中...")
}
checkType<String>("Hello") // Hello 是 String 类型
checkType<Int>(123) // 123 是 Int 类型
}
4. 尾递归函数 (Tail Recursive Functions)
使用 tailrec 优化递归调用
// 普通递归(可能导致栈溢出)
fun factorial(n: Int): Int {
return if (n <= 1) 1 else n * factorial(n - 1)
}
// 尾递归优化版本
tailrec fun factorialTailrec(n: Int, accumulator: Int = 1): Int {
return if (n <= 1) accumulator else factorialTailrec(n - 1, n * accumulator)
}
// 尾递归查找
tailrec fun findIndex(array: IntArray, target: Int, index: Int = 0): Int {
return when {
index >= array.size -> -1
array[index] == target -> index
else -> findIndex(array, target, index + 1)
}
}
fun main() {
println(factorialTailrec(5)) // 120
val numbers = intArrayOf(1, 3, 5, 7, 9)
println(findIndex(numbers, 5)) // 2
println(findIndex(numbers, 2)) // -1
}
5. 操作符重载函数 (Operator Overloading Functions)
重载运算符
data class Vector(val x: Int, val y: Int) {
// 重载 + 运算符
operator fun plus(other: Vector): Vector {
return Vector(x + other.x, y + other.y)
}
// 重载 - 运算符
operator fun minus(other: Vector): Vector {
return Vector(x - other.x, y - other.y)
}
// 重载 * 运算符
operator fun times(scalar: Int): Vector {
return Vector(x * scalar, y * scalar)
}
// 重载 [] 运算符
operator fun get(index: Int): Int {
return when(index) {
0 -> x
1 -> y
else -> throw IndexOutOfBoundsException("Invalid index $index")
}
}
// 重载 in 运算符
operator fun contains(value: Int): Boolean {
return value == x || value == y
}
}
fun main() {
val v1 = Vector(1, 2)
val v2 = Vector(3, 4)
println(v1 + v2) // Vector(x=4, y=6)
println(v2 - v1) // Vector(x=2, y=2)
println(v1 * 3) // Vector(x=3, y=6)
println(v1[0]) // 1
println(v1[1]) // 2
println(3 in v2) // true
println(5 in v2) // false
}
6. 泛型函数 (Generic Functions)
使用类型参数
// 简单的泛型函数
fun <T> printItem(item: T) {
println("Item: $item")
}
// 多个类型参数
fun <T, R> mapList(list: List<T>, transform: (T) -> R): List<R> {
return list.map(transform)
}
// 泛型约束
fun <T : Comparable<T>> maxOf(first: T, second: T): T {
return if (first > second) first else second
}
// 多个约束
fun <T> process(value: T) where T : CharSequence, T : Appendable {
println("长度: ${value.length}")
value.append("!")
}
// 泛型扩展函数
fun <T> List<T>.secondOrNull(): T? {
return if (size >= 2) this[1] else null
}
fun main() {
printItem(123) // Item: 123
printItem("Hello") // Item: Hello
val numbers = listOf(1, 2, 3)
val squared = mapList(numbers) { it * it }
println(squared) // [1, 4, 9]
println(maxOf(10, 20)) // 20
println(maxOf("a", "b")) // b
val strings = listOf("a", "b", "c")
println(strings.secondOrNull()) // b
}
三、按使用方式分类
1. 高阶函数 (Higher-Order Functions)
接收函数作为参数或返回函数
// 接收函数参数
fun calculate(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
return operation(a, b)
}
// 返回函数
fun getMultiplier(factor: Int): (Int) -> Int {
return { number -> number * factor }
}
// 使用函数引用
fun isEven(number: Int): Boolean = number % 2 == 0
fun processNumbers(numbers: List<Int>, predicate: (Int) -> Boolean): List<Int> {
return numbers.filter(predicate)
}
fun main() {
// 传递 lambda
val sum = calculate(5, 3) { x, y -> x + y }
println("Sum: $sum") // 8
// 传递函数引用
val numbers = listOf(1, 2, 3, 4, 5)
val evens = processNumbers(numbers, ::isEven)
println("偶数: $evens") // [2, 4]
// 使用返回的函数
val double = getMultiplier(2)
println(double(5)) // 10
}
2. Lambda 表达式
匿名函数
fun main() {
// Lambda 基本形式
val add: (Int, Int) -> Int = { a, b -> a + b }
// 类型推断
val multiply = { a: Int, b: Int -> a * b }
// 单参数 lambda 的隐式参数名 it
val numbers = listOf(1, 2, 3, 4, 5)
val squares = numbers.map { it * it }
// 带接收者的 lambda
val builder = StringBuilder().apply {
append("Hello")
append(" ")
append("World")
}
println(add(3, 4)) // 7
println(multiply(3, 4)) // 12
println(squares) // [1, 4, 9, 16, 25]
println(builder) // Hello World
}
3. 匿名函数 (Anonymous Functions)
没有名称的函数表达式
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
// 使用 lambda
val lambdaSum = numbers.reduce { acc, num -> acc + num }
// 使用匿名函数
val anonymousSum = numbers.reduce(fun(acc: Int, num: Int): Int {
return acc + num
})
// 匿名函数的 return 从自身返回
val firstEven = numbers.find(fun(num: Int): Boolean {
if (num % 2 == 0) {
return true // 只从匿名函数返回
}
return false
})
println("Lambda 求和: $lambdaSum") // 15
println("匿名函数求和: $anonymousSum") // 15
println("第一个偶数: $firstEven") // 2
}
4. 函数引用 (Function References)
引用已有函数
fun isPositive(number: Int): Boolean = number > 0
fun square(number: Int): Int = number * number
class MathUtils {
fun cube(number: Int): Int = number * number * number
}
fun main() {
val numbers = listOf(-2, -1, 0, 1, 2)
// 顶层函数引用
val positives = numbers.filter(::isPositive)
println("正数: $positives") // [1, 2]
// 成员函数引用
val utils = MathUtils()
val cubes = numbers.map(utils::cube)
println("立方: $cubes") // [-8, -1, 0, 1, 8]
// 构造函数引用
data class Person(val name: String, val age: Int)
val createPerson = ::Person
val person = createPerson("Alice", 25)
println(person) // Person(name=Alice, age=25)
// 绑定函数引用
val alice = Person("Alice", 25)
val getAge = Person::age
println("Alice的年龄: ${getAge(alice)}") // 25
}
四、特殊函数类型
1. 挂起函数 (Suspending Functions)
用于协程
import kotlinx.coroutines.*
// 挂起函数
suspend fun fetchData(): String {
delay(1000) // 模拟耗时操作
return "Data loaded"
}
// 挂起函数调用其他挂起函数
suspend fun processData(): String {
val data = fetchData()
return data.uppercase()
}
// 带有超时的挂起函数
suspend fun fetchWithTimeout(): String? {
return withTimeoutOrNull(500) {
fetchData()
}
}
fun main() = runBlocking {
println("开始获取数据...")
// 启动协程执行挂起函数
val result = fetchData()
println("结果: $result")
// 并发执行多个挂起函数
val deferred1 = async { fetchData() }
val deferred2 = async { fetchData() }
val results = awaitAll(deferred1, deferred2)
println("并发结果: $results")
}
2. 密封接口/类的函数 (Sealed Class Functions)
配合密封类使用
sealed class Result<out T> {
// 密封类中的函数
fun isSuccess(): Boolean = this is Success
fun isError(): Boolean = this is Error
// 扩展函数模式
fun getOrNull(): T? = when (this) {
is Success -> value
is Error -> null
}
data class Success<out T>(val value: T) : Result<T>()
data class Error(val message: String) : Result<Nothing>()
}
fun processResult(result: Result<Int>) {
when (result) {
is Result.Success -> println("成功: ${result.value}")
is Result.Error -> println("错误: ${result.message}")
}
}
fun main() {
val success = Result.Success(42)
val error = Result.Error("出错了")
processResult(success) // 成功: 42
processResult(error) // 错误: 出错了
println(success.getOrNull()) // 42
println(error.getOrNull()) // null
}
3. DSL 构建器函数 (DSL Builder Functions)
用于创建领域特定语言
class Html {
private val children = mutableListOf<String>()
fun body(block: Body.() -> Unit) {
val body = Body().apply(block)
children.add(body.toString())
}
override fun toString() = children.joinToString("\n")
}
class Body {
private val elements = mutableListOf<String>()
fun h1(text: String) {
elements.add("<h1>$text</h1>")
}
fun p(text: String) {
elements.add("<p>$text</p>")
}
fun div(block: Div.() -> Unit) {
val div = Div().apply(block)
elements.add(div.toString())
}
override fun toString() = elements.joinToString("\n")
}
class Div {
private var className = ""
private var content = ""
fun className(name: String) {
className = " class=\"$name\""
}
operator fun String.unaryPlus() {
content = this
}
override fun toString() = "<div$className>$content</div>"
}
fun html(block: Html.() -> Unit): Html {
return Html().apply(block)
}
fun main() {
val page = html {
body {
h1("Welcome")
p("This is a paragraph")
div {
className = "container"
+"Some content"
}
}
}
println(page)
}
五、函数特性组合
1. 扩展函数 + 中缀
infix fun String.repeat(times: Int): String = this.repeat(times)
fun main() {
println("ha" repeat 3) // hahaha
}
2. 泛型 + 扩展函数
fun <T> List<T>.secondOrNull(): T? = if (size >= 2) this[1] else null
fun main() {
val list = listOf("a", "b", "c")
println(list.secondOrNull()) // b
}
3. 内联 + 泛型
inline fun <reified T> List<*>.filterByType(): List<T> {
return filterIsInstance<T>()
}
fun main() {
val mixed = listOf(1, "two", 3, "four", 5)
val numbers = mixed.filterByType<Int>()
val strings = mixed.filterByType<String>()
println("数字: $numbers") // [1, 3, 5]
println("字符串: $strings") // [two, four]
}
六、函数类型别名
// 为函数类型定义别名
typealias Predicate<T> = (T) -> Boolean
typealias StringMapper = (String) -> String
typealias BinaryOperation = (Int, Int) -> Int
// 使用类型别名
fun filterList(list: List<Int>, predicate: Predicate<Int>): List<Int> {
return list.filter(predicate)
}
// 高阶函数返回类型别名
fun createValidator(): Predicate<String> {
return { it.length > 5 }
}
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
val evens = filterList(numbers) { it % 2 == 0 }
println("偶数: $evens") // [2, 4]
val validator = createValidator()
println(validator("short")) // false
println(validator("longer")) // true
}
总结对比表
| 函数类别 | 关键字/特征 | 主要用途 | 示例 |
|---|---|---|---|
| 顶层函数 | 无 | 工具函数、辅助函数 | fun calculate() {} |
| 成员函数 | 类内部 | 对象行为、方法 | class A { fun foo() {} } |
| 扩展函数 | fun Type. | 为现有类添加功能 | fun String.customFun() {} |
| 中缀函数 | infix | 提高可读性 | infix fun Int.add(x: Int) |
| 内联函数 | inline | 减少高阶函数开销 | inline fun<T> process() |
| 尾递归 | tailrec | 递归优化 | tailrec fun factorial() |
| 操作符重载 | operator | 自定义运算符行为 | operator fun plus() |
| 泛型函数 | <T> | 类型安全复用 | fun <T> process(item: T) |
| 高阶函数 | 函数参数/返回值 | 函数式编程 | fun map(transform: (T)->R) |
| 挂起函数 | suspend | 协程异步编程 | suspend fun fetchData() |
| 密封类函数 | 密封类内部 | 受限类型处理 | sealed class Result |
最佳实践建议
- 优先使用顶层函数:对于工具函数,优先考虑定义为顶层函数
- 合理使用扩展函数:为系统类添加常用功能时使用
- 高阶函数内联化:对于频繁调用的高阶函数,考虑使用
inline - 类型安全优先:充分利用泛型保证类型安全
- DSL 模式:构建领域特定语言时使用接收者函数
- 函数式组合:通过函数组合实现复杂逻辑
- 避免过度嵌套:控制 lambda 嵌套深度,保持可读性
- 合理命名:函数名应清晰表达其意图
Kotlin 的函数系统非常强大和灵活,合理利用不同函数类型可以写出更简洁、安全、高效的代码。