函数进阶
参数默认不可变
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]
设计原则:
- 基本类型(整型等)禁止修改
- 优先返回新值而非修改参数(如
user.register()
) - 高性能场景才修改参数以减少内存分配
可变数量参数
用 ...类型
接收可变参数:
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 将在所有这些之后打印。