首页 / Android 入门教程 / 函数

Android 入门教程

函数

本教程共 100 篇 · 第 12 篇 · 更新于 2026-07-28 · 约 7 分钟阅读

AndroidAndroid 入门教程Kotlin函数默认参数命名参数扩展函数顶层函数

12. 函数

本节目标:学会声明函数、用默认参数和命名参数简化调用、理解顶层函数和扩展函数这些 Kotlin 特色,知道局部函数什么时候用。

函数声明

fun 关键字声明:

fun add(a: Int, b: Int): Int {
    return a + b
}
  • fun 是关键字。
  • 参数写 名: 类型
  • 返回类型写在参数列表后,用 : 分隔。
  • 没有返回值用 Unit(可省略,相当于 Java 的 void)。

表达式函数体

函数体只有一句返回时,可以简写成表达式:

fun add(a: Int, b: Int): Int = a + b

// 返回类型也能推断
fun add(a: Int, b: Int) = a + b

无返回值

fun log(message: String): Unit {     // Unit 可省略
    println(message)
}

fun log(message: String) {
    println(message)
}

默认参数

Kotlin 函数参数能有默认值,调用时可以省略:

fun greet(name: String, greeting: String = "Hello") {
    println("$greeting, $name!")
}

greet("Android")                  // Hello, Android!
greet("Android", "Hi")            // Hi, Android!
Tip
  • 默认参数能大幅减少方法重载。Java 里要写好几个 greet 重载,Kotlin 一个函数搞定。

命名参数

参数多时按位置传容易出错,可以用命名参数:

fun createUser(name: String, age: Int = 0, email: String = "", isAdmin: Boolean = false) {
    // ...
}

createUser(name = "张三", isAdmin = true)
createUser("李四", email = "li@example.com")

命名参数让调用意图清晰,特别是布尔参数,isAdmin = truetrue 好读多了。

Note
  • 命名参数和默认参数配合,能写出非常灵活的 API。但调用 Java 代码时不能用命名参数(Java 不保留参数名信息,除非编译加 -parameters)。

顶层函数

Kotlin 不强制所有函数都放在类里。你可以直接在文件顶层写函数:

// Utils.kt
fun formatDate(timestamp: Long): String {
    // ...
}

fun isValidEmail(email: String): Boolean {
    // ...
}

调用时直接用,不用 Utils.formatDate(...)(虽然底层编译成静态方法)。Android 里工具函数都这么写,比 Java 那种塞满 Utils 类的写法干净。

// 在别的文件里
val date = formatDate(System.currentTimeMillis())

扩展函数

Kotlin 的杀手锏之一。能给已有类(包括系统类、第三方库类)加新方法,不改源码,不用继承。

语法:fun 接收者类型.函数名(...)

// 给 String 加个扩展函数
fun String.isEmail(): Boolean {
    return this.contains("@") && this.contains(".")
}

// 用起来就像原生方法
val valid = "test@example.com".isEmail()

this 指调用对象本身。扩展函数不真的修改原类,编译后是静态方法,但用起来跟成员方法一样。

Android 里常用扩展函数封装常用操作:

// 给 View 加点击防抖
fun View.onThrottleClick(interval: Long = 500, action: () -> Unit) {
    setOnClickListener {
        // 防抖逻辑
        action()
    }
}

// 给 Context 加显示 Toast
fun Context.toast(message: String) {
    android.widget.Toast.makeText(this, message, android.widget.Toast.LENGTH_SHORT).show()
}

// 给 Int 加 dp 转 px
fun Int.dpToPx(context: Context): Float {
    return this * context.resources.displayMetrics.density
}
Warning
  • 扩展函数是静态解析的,不是多态。给父类写的扩展,子类对象调用时执行的是父类的扩展。这跟成员方法的多态不一样,注意区分。

局部函数

函数里还能定义函数,作用域限定在外层函数内:

fun processUser(user: User): String {
    fun validate(field: String, value: String): Boolean {
        return value.isNotBlank()
    }

    if (!validate("name", user.name)) return "名字为空"
    if (!validate("email", user.email)) return "邮箱为空"
    return "校验通过"
}

局部函数能访问外层函数的变量,适合把一个大函数里重复的小逻辑提出来,又不想污染外部作用域。

可变参数

vararg 表示参数个数不定:

fun sum(vararg numbers: Int): Int {
    return numbers.sum()
}

sum(1, 2, 3)           // 6
sum(1, 2, 3, 4, 5)     // 15

传数组用展开运算符 *

val arr = intArrayOf(1, 2, 3)
sum(*arr)              // 6

infix 中缀函数

infix 修饰的函数,调用时可以省略点和括号:

infix fun Int.times(str: String): String {
    return str.repeat(this)
}

val result = 3 times "ab"     // 等同于 3.times("ab")
println(result)               // ababab

Kotlin 内置的 tountilstepin 都是中缀函数。自定义场景用在 DSL 或语义清晰时,别滥用。

Android 实战示例

// 顶层工具函数
fun formatPrice(cents: Long): String {
    return "¥${"%.2f".format(cents / 100.0)}"
}

// 扩展函数:给 ViewModel 加协程启动
fun ViewModel.launch(
    onError: (Throwable) -> Unit = {},
    block: suspend () -> Unit
) {
    viewModelScope.launch {
        try { block() } catch (e: Throwable) { onError(e) }
    }
}

// 带默认参数的 Compose 工具
@Composable
fun LoadingButton(
    text: String,
    onClick: () -> Unit,
    isLoading: Boolean = false,
    enabled: Boolean = true,
    modifier: Modifier = Modifier
) {
    // ...
}

小结

fun 声明函数,表达式体能简写。默认参数 + 命名参数减少重载。顶层函数不用塞类。扩展函数给已有类加方法,是 Kotlin 利器。局部函数提小逻辑。vararg 接可变参数。下一节学类与对象。