欢迎光临
我们一直在努力

5-Kotlin核心语法-函数

Kotlin 函数(Function)全面解析

函数是 Kotlin 中最核心的代码复用和逻辑封装单元,相比 Java 提供了更灵活、简洁、强大的语法特性。本文从基础到进阶,结合代码示例详细讲解函数的核心知识点,并附上官方权威资料链接。


一、函数基础

1. 函数定义语法

Kotlin 函数使用 fun 关键字声明,基本结构如下:

// 修饰符 fun 函数名(参数名: 参数类型): 返回值类型 { 函数体 }
fun add(a: Int, b: Int): Int {
return a + b
}

  • 修饰符(可选):如 public(默认)、private、internal、protected、inline 等;
  • 参数:格式为 参数名: 类型,支持默认值、命名参数;
  • 返回值:无返回值时可写 Unit(可省略),相当于 Java 的 void。

2. 无返回值函数

// 方式1:显式声明返回 Unit
fun printHello(name: String): Unit {
println("Hello, $name!")
}

// 方式2:省略 Unit(推荐)
fun printWelcome(name: String) {
println("Welcome, $name!")
}

3. 单表达式函数

如果函数体只有一个表达式,可以省略花括号和 return,直接用 = 连接:

// 等价于上面的 add 函数,更简洁
fun add(a: Int, b: Int): Int = a + b

// 返回值类型可自动推导
fun multiply(a: Int, b: Int) = a * b

4. 最简单的函数

fun sayHello() {
println("Hello!")
}

fun main() {
sayHello()
}


二、函数的参数

1. 传统位置参数调用

按参数定义顺序传递参数:

fun greet(name: String, age: Int) {
println("Name: $name, Age: $age")
}

fun main() {
greet("Alice", 25) // 顺序必须一致
}

2. 命名参数

调用时可以显式指定参数名,从而可以打乱顺序,提高可读性:

fun main() {
greet(age = 25, name = "Alice") // 使用命名参数,顺序可以调换
}

3. 默认参数

参数可以有默认值,调用时如果省略该参数,则使用默认值,避免 Java 中的重载冗余:

// 给 b 设置默认值 10
fun calculate(a: Int, b: Int = 10, c: Int = 5): Int {
return a + b * c
}

fun main() {
println(calculate(2)) // 2 + 10*5 = 52(使用 b、c 的默认值)
println(calculate(2, 3)) // 2 + 3*5 = 17(仅覆盖 b 的默认值)
println(calculate(2, 3, 4)) // 2 + 3*4 = 14(覆盖所有参数)
// 命名参数可以跳过中间的默认参数
println(calculate(a = 2, c = 8)) // 2 + 10*8 = 82
}

注意:如果默认参数位于非默认参数之前,只能通过命名参数调用才能省略前面的参数:

fun greet(greeting: String = "Hello", name: String) { // 默认参数在前
println("$greeting, $name")
}

fun main() {
greet(name = "Alice") // 必须使用命名参数,因为第一个参数被省略
}

4. 可变数量的参数(vararg)

使用 vararg 修饰符声明一个参数,表示可以接受可变数量的参数(类似 Java 的可变参数)。在函数内部,可变参数表现为对应类型的数组。

fun sum(vararg numbers: Int): Int {
var total = 0
for (num in numbers) {
total += num
}
return total
}

fun main() {
println(sum(1, 2, 3)) // 6
println(sum(10, 20, 30, 40)) // 100
}

展开操作符(Spread Operator)

当你已经有一个数组,想要将其内容传递给 vararg 参数时,可以使用 * 操作符展开数组:

fun main() {
val arr = intArrayOf(5, 6, 7)
println(sum(*arr)) // 18
// 可以混合普通参数和展开的数组
println(sum(1, *arr, 2)) // 1+5+6+7+2 = 21
}


三、函数的高级形式

1. 局部函数(嵌套函数)

Kotlin 支持在函数内部定义另一个函数,称为局部函数。局部函数可以访问外部函数的局部变量,常用于功能封装和避免代码重复。

fun validateUser(username: String, password: String): Boolean {
// 局部函数:校验非空
fun checkNotEmpty(str: String, msg: String) {
if (str.isEmpty()) {
throw IllegalArgumentException(msg)
}
}

checkNotEmpty(username, "用户名不能为空")
checkNotEmpty(password, "密码不能为空")

// 模拟校验逻辑
return username.length >= 6 && password.length >= 8
}

fun main() {
println(validateUser("kotlin123", "12345678")) // true
// validateUser("", "12345678") // 抛出异常
}

2. 中缀函数(infix)

用 infix 关键字修饰的函数,允许使用中缀表示法调用(即省略点号和括号),但必须满足以下条件:

  • 必须是成员函数或扩展函数;
  • 只有一个参数;
  • 参数不能是可变参数且不能有默认值。

infix fun Int.add(other: Int): Int = this + other

fun main() {
val result = 3 add 5 // 中缀调用,等价于 3.add(5)
println(result) // 8
}

常见的中缀函数如 to(用于创建 Pair):1 to "one"。

3. 尾递归函数(tailrec)

当一个函数调用自身作为其最后一个操作(尾调用)时,可以使用 tailrec 修饰符,编译器会将递归优化为迭代,避免栈溢出。

tailrec fun factorial(n: Int, accumulator: Int = 1): Int {
return if (n <= 1) accumulator else factorial(n – 1, n * accumulator)
}

fun main() {
println(factorial(5)) // 120
}

注意:tailrec 要求递归调用必须是函数的最后一个操作,并且不能用在 try/catch/finally 块中。

4. 扩展函数

扩展函数可以在不继承类的情况下,为现有类添加新函数。扩展函数是静态解析的,并非真正修改类。

// 给 String 类扩展一个 "统计数字个数" 的函数
fun String.countDigits(): Int {
var count = 0
for (char in this) { // this 指代调用扩展函数的 String 实例
if (char.isDigit()) {
count++
}
}
return count
}

fun main() {
val str = "Kotlin12345Java678"
println(str.countDigits()) // 输出 8(12345678)
}

扩展函数可以访问接收者对象的公有成员,但不能访问私有或 protected 成员。

5. 泛型函数

函数可以声明类型参数,使其适用于多种类型。

fun <T> identity(value: T): T = value

fun main() {
val intResult = identity(42) // T 推断为 Int
val stringResult = identity("Kotlin") // T 推断为 String
println(intResult)
println(stringResult)
}

可以同时有多个类型参数,并对类型参数进行上界约束:

fun <T : Comparable<T>> max(a: T, b: T): T {
return if (a > b) a else b
}

fun main() {
println(max(10, 20)) // 20
println(max("A", "B")) // B
}


四、高阶函数与函数类型

1. 函数类型定义

函数类型格式:(参数类型1, 参数类型2) -> 返回值类型,例如:

  • (Int, Int) -> Int:接收两个 Int,返回 Int 的函数;
  • () -> Unit:无参数、无返回值的函数。

2. 高阶函数示例

高阶函数是指将函数作为参数或返回值的函数。

// 高阶函数:接收两个 Int 和一个函数类型参数
fun operate(a: Int, b: Int, op: (Int, Int) -> Int): Int {
return op(a, b) // 调用传入的函数
}

fun main() {
// 调用高阶函数:传入 lambda 表达式作为参数
val result1 = operate(10, 5) { x, y -> x + y } // 加法
val result2 = operate(10, 5) { x, y -> x * y } // 乘法
println(result1) // 15
println(result2) // 50
}

3. 内联函数(inline)

高阶函数通常会创建 lambda 的匿名类对象,带来一定的运行时开销。使用 inline 关键字修饰高阶函数,可以在调用处将函数体直接内联展开,避免创建匿名对象,提升性能。

// 内联高阶函数
inline fun logTime(block: () -> Unit) {
val start = System.currentTimeMillis()
block()
val end = System.currentTimeMillis()
println("执行耗时:${end – start}ms")
}

fun main() {
logTime {
Thread.sleep(100)
println("逻辑执行完成")
}
}

注意:inline 通常用于高阶函数,如果普通函数被标记为 inline,编译器也会内联,但通常没有性能收益,反而会增加字节码大小。


五、函数的作用域

1. 顶层函数

直接定义在文件中的函数,不属于任何类,可以从任意位置导入使用(类似 Java 的静态方法)。Kotlin 的顶层函数会被编译为对应文件名加 Kt 后缀的类的静态方法。

// File: Utils.kt
package com.example.utils

fun topLevelFunction() {
println("I'm a top-level function")
}

2. 成员函数

定义在类内部的函数,需要通过类的实例调用(或通过类名调用伴生对象中的函数)。

class MyClass {
fun memberFunction() {
println("Member function")
}
}

fun main() {
MyClass().memberFunction()
}

3. 局部函数

前面已介绍,定义在其他函数内部。


六、完整示例:综合运用

以下示例综合展示了多种函数特性:

// 顶层函数
fun main() {
println("计算结果:${calculate(10, 5)}")
printNumbers(1, 2, 3, 4, 5)

val greeting = "Kotlin"
println(greeting.addExclamation())

println(maxOf(10, 20))

// 高阶函数示例
logTime {
println("执行一些操作")
}
}

// 单表达式函数 + 默认参数
fun calculate(a: Int, b: Int, operation: String = "add") = when (operation) {
"add" -> a + b
"sub" -> a – b
else -> 0
}

// 可变参数 + 局部函数
fun printNumbers(vararg numbers: Int) {
fun printFormatted(num: Int) {
println("Number: $num")
}
for (n in numbers) printFormatted(n)
}

// 扩展函数
fun String.addExclamation() = "$this!"

// 泛型函数
fun <T : Comparable<T>> maxOf(a: T, b: T): T = if (a > b) a else b

// 内联高阶函数
inline fun logTime(block: () -> Unit) {
val start = System.currentTimeMillis()
block()
val end = System.currentTimeMillis()
println("耗时:${end – start}ms")
}


七、官方资料链接

  • Kotlin 函数核心文档(官方英文): https://kotlinlang.org/docs/functions.html
  • Kotlin 函数中文文档(官方授权翻译): https://www.kotlincn.net/docs/reference/functions.html
  • Kotlin 高阶函数与 lambda: https://kotlinlang.org/docs/lambdas.html
  • Kotlin 扩展函数: https://kotlinlang.org/docs/extensions.html
  • Kotlin 内联函数: https://kotlinlang.org/docs/inline-functions.html
  • Kotlin 泛型函数: https://kotlinlang.org/docs/generics.html#generic-functions

  • 总结

  • 核心基础:Kotlin 函数用 fun 声明,支持单表达式简写、默认参数、命名参数,比 Java 更简洁;
  • 进阶特性:可变参数(vararg)、局部函数、中缀函数、尾递归、扩展函数、泛型函数是 Kotlin 函数的核心优势;
  • 函数式编程:高阶函数和 lambda 表达式让 Kotlin 支持强大的函数式编程范式;
  • 性能优化:内联函数(inline)可解决高阶函数的性能损耗。
  • 掌握这些函数特性,能够让你编写出更简洁、更灵活、更高效的 Kotlin 代码。

     

    赞(0)
    未经允许不得转载:171主机测评 » 5-Kotlin核心语法-函数
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址