函数进阶

参数默认不可变

V语言中函数参数默认不可变,需显式标记 mut 才能修改:

  • 无全局变量设计使函数返回值仅取决于参数(I/O操作除外)
  • 所有参数(包括引用传递)默认不可变
  • 内核/驱动等低级应用可通过 -enable-globals 启用全局变量

V 并非纯函数式语言,但通过此设计提升代码可预测性。

可变参数

标记 mut 允许函数修改参数:

fn multiply_by_2(mut arr []int) {
    for i in 0 .. arr.len {
        arr[i] *= 2
    }
}

mut nums := [1, 2, 3]
multiply_by_2(mut nums)  // 调用时需显式加 mut
println(nums)  // 输出: [2, 4, 6]

设计原则:

  1. 基本类型(整型等)禁止修改
  2. 优先返回新值而非修改参数(如 user.register()
  3. 高性能场景才修改参数以减少内存分配

可变数量参数

...类型 接收可变参数:

fn sum(a ...int) int {
    mut total := 0
    for x in a { total += x }
    return total
}

// 使用示例
println(sum(1, 2, 3))         // 6
arr := [4, 5, 6]
println(sum(...arr))          // 15 (数组解构)

匿名函数与高阶函数

函数可作为参数/返回值:

// 高阶函数:接收函数作为参数
fn run(n int, op fn(int) int) int {
    return op(n)
}

// 匿名函数
cube := fn(n int) int { return n*n*n }

println(run(3, cube))  // 27

// 函数集合
funcs := [fn(n int)int{return n*2}, cube]
println(funcs[0](10))   // 20

闭包

匿名函数可捕获外部变量(需显式声明):

// 基础闭包
mut counter := 0
cl := fn [counter] () int {
    return counter + 1  // 捕获创建时的值
}
println(cl()) // 1 (不受后续修改影响)

// 计数器工厂
fn counter() fn() int {
    mut i := 0
    return fn [mut i] () int { // 捕获可变变量
        i++
    return i
}
}
c := counter()
println(c(), c()) // 1, 2

参数求值顺序

V不保证函数参数求值顺序:

fn f(a1 int, a2 int, a3 int) {
    dump(a1 + a2 + a3)
}

fn main() {
    f(dump(100), dump(200), dump(300))
}

// V 目前不保证它将按该顺序打印 100、200、300。唯一的保证是 600 将在所有这些之后打印。