【发布时间】:2020-12-17 13:00:20
【问题描述】:
运行以下 Go 代码的 sn-p 可以实现函数 foo 在评估函数的第二个参数时接收实际设置的第一个参数的值。这种行为可能看起来违反直觉,因此我们需要证明这是语言规范的一部分,而不是特定于实现的东西。
package main
import (
"fmt"
)
func setVal(s *int, v int) int {
old := *s
*s = v
return old
}
func foo(s int, p int) {
fmt.Printf("s = %d, p = %d\n", s, p)
}
func main() {
var s int
foo(s, setVal(&s, 99))
}
程序输出s = 99, p = 0,这意味着变量s的修改值已传递给函数。
这是 Go 规范关于此案例的说明。
在function call 中,...参数必须是单值表达式...参数按通常的顺序计算。求值后,调用的参数按值传递给函数...其中usual order是从左到右的词法顺序。
variable 是用于保存值的存储位置。 ...通过引用表达式中的变量来检索变量的值;它是分配给变量的最新值。
因此foo(s, setVal(&s, 99))是一个函数调用,变量s和函数setVal()是单值表达式,s首先被求值。最后一个规范语句假设变量评估的结果是它的值,所以如果这是真的,函数foo应该接收变量s的初始值。
但实际上看起来函数接收到的第一个参数的值是在评估第二个参数时设置的,这有点令人困惑。
这是否意味着评估顺序被破坏或变量评估的结果不是它的值?
【问题讨论】:
标签: go expression specifications