函数声明与默认参数
Kotlin 函数 (Fun) 是"一等公民"。通过简化语法、默认参数和中缀调用,它极大地增强了代码的表达力与灵活性。
基础语法
Kotlin 支持两种函数体形式:代码块体与表达式体。
kotlin
fun add(a: Int, b: Int): Int {
return a + b
}kotlin
// 自动推导返回类型,代码更紧凑
fun multiply(a: Int, b: Int) = a * b返回值 Unit
如果函数不返回任何有意义的值,其返回类型为 Unit (对应 Java 的 void)。Unit 类型声明通常省略。
kotlin
fun log(message: String) { // : Unit 已省略
println(message)
}作用域与可见性
Kotlin 函数可以定义在文件顶层,无需像 Java 那样必须包裹在类中。
| 可见性修饰符 | 说明 |
|---|---|
public | (默认) 随处可见 |
internal | 同一模块 (Module) 内可见 |
protected | 子类可见 (仅限类成员) |
private | 文件内或类内可见 |
局部函数 (Local Functions)
你可以在函数内部定义函数,支持闭包 (访问外部变量)。
kotlin
fun saveUser(user: User) {
// 局部函数:封装重复校验逻辑
fun validate(value: String, field: String) {
if (value.isEmpty()) throw IllegalArgumentException("$field is empty")
}
validate(user.name, "Name")
validate(user.email, "Email")
// ...
}默认参数与具名参数 (Named Arguments)
这是 Kotlin 减少重载 (Overload) 数量的神器。
kotlin
fun reformat(
str: String,
normalizeCase: Boolean = true,
upperCaseFirstLetter: Boolean = true,
divideByCamelHumps: Boolean = false,
wordSeparator: Char = ' '
) { /*...*/ }
// 调用时可以只传部分参数,且不依赖顺序
reformat("String!", wordSeparator = '_')Java 互操作:@JvmOverloads
Java 不支持默认参数。为了在 Java 中也能方便调用,需要添加 @JvmOverloads 注解,编译器会生成多个重载方法。 这对自定义 Android View (构造函数重载) 尤其重要。
kotlin
class CustomView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr)中缀函数 (Infix Functions)
中缀函数允许省略点号和括号,让代码像自然语言一样流畅。典型场景是 map 的 to。
kotlin
// 定义扩展函数为 infix
infix fun Int.vs(other: Int): String {
return if (this > other) "Win" else "Lose"
}
// 调用
val gameResult = 5 vs 3 // 输出 "Win"
// 标准库示例:构建 Pair
val map = mapOf(
"Key" to "Value", // "Key".to("Value")
"User" to "Admin"
)变长参数 (Varargs)
使用 vararg 关键字接收不定数量的参数。
kotlin
fun <T> asList(vararg ts: T): List<T> {
val result = ArrayList<T>()
for (t in ts) result.add(t)
return result
}
val list = asList(1, 2, 3)
// 伸展操作符 (Spread Operator): *
// 将已有的数组展开传入
val array = arrayOf(7, 8, 9)
val combined = asList(1, 2, *array)尾递归优化 (Tail Recursion)
对于算法中的递归调用,使用 tailrec 修饰符可以让编译器将其优化为高效的循环 (Loop),避免 StackOverflowError。
kotlin
tailrec fun gcd(a: Int, b: Int): Int {
// 递归调用必须是函数的最后一个操作
return if (b == 0) a else gcd(b, a % b)
}