可变接收器及纯函数(Mutable receivers & pure functions)


默认情况下,V语言中函数是纯函数,这意味着它们的返回值只由它们的参数决定,而且函数的计算求值时不会造成side effects。这是由于缺少全局变量和所有函数参数在默认情况下是不可变的,即使在传递引用时也是如此。
然而,V语言不是一种纯粹的函数式语言。可以通过使用相同的关键字var来修改函数参数:

struct User {
var:
    is_registered bool
}
 
fn (var u User) register() {
    u.is_registered = true
}
 
var user := User{}
println(user.is_registered) // "false"
user.register()
println(user.is_registered) // "true"

在本例中,receiver(它只是第一个参数)被标记为可变的,因此register()可以更改user对象。同样适用于非接收方参数:

fn multiply_by_2(var arr []int) {
    for i in 0..arr.len {
        arr[i] *= 2
    }
}
 
var nums := [1, 2, 3]
multiply_by_2(var nums)
println(nums) // "[2, 4, 6]"


注意,在调用这个函数时,必须在nums之前添加var。这表明被调用的函数将修改值。
最好用返回值来代替去修改参数。只应在应用程序的性能关键部分中修改参数,以减少分配和复制。
由于这个原因,V语言是不允许像整数那样修改原始参数,只允许像数组和映射这样的复杂类型中修改。
使用user.register()或user = register(user)而不是register(var user)。
V语言这样的设计就可以很容易返回一个对象的修改版本:

fn register(u User) User {
    return { u | is_registered: true }
}
 
user = register(user)