因此,根据规范,在调用 defer 函数时会评估 defer 函数中的值,但在封闭函数返回之前不会执行操作。我明白了,并理解了整个 'for i:=0;i<4;i++ defer example prints 3210' 的事情。但是,当我尝试使用 defer 临时分配覆盖值(将 max m 分配给队列长度 q)时,请确保在完成后重置该值(示例简化为演示):type tss struct { q int m int}func (t *tss) test() { if true { defer func() { t.q=t.q //this should evaluate to 't.q = 50' right? fmt.Println("assigned",t.q,"to t.q") }() t.q = t.m } fmt.Printf("q=%v, m=%v\n", t.q, t.m)}func main() { ts := tss{50,1} fmt.Printf("q=%v, m=%v\n", ts.q, ts.m) ts.test() fmt.Printf("q=%v, m=%v\n", ts.q, ts.m)}我希望收到输出:q=50, m=1q=1, m=1assigned 50 to t.qq=50, m=1但实际输出是:q=50, m=1q=1, m=1assigned 1 to t.qq=1, m=1因此,这些值似乎是在错误的时间进行评估的。但是,当我首先将 tq 转储到变量中并将该赋值移到延迟函数之外,并将测试函数更改为如下所示:func (t *tss) test() { if true { qtmp := t.q defer func() { //assigning qtmp here still assigns 1 back to t.q t.q=qtmp fmt.Println("assigned",t.q,"to t.q") }() t.q = t.m } fmt.Printf("q=%v, m=%v\n", t.q, t.m)}我得到了上面的预期输出,其中分配了 50。我是否遇到了错误,或者是否有关于在我缺少的延迟函数中分配值的问题?可能值得注意的是,如果我将 tq 作为函数参数传入,它也能正常工作:func (t *tss) test() { if true { defer func(q int) { t.q=q fmt.Println("assigned",t.q,"to t.q") }(t.q) t.q = t.m } fmt.Printf("q=%v, m=%v\n", t.q, t.m)}
2 回答
一只甜甜圈
TA贡献1836条经验 获得超5个赞
所以我在校对我的帖子时回答了我自己的问题。与其删除它以掩饰我的尴尬,不如将其保留,以防其他人遭受同样的困惑。
deferred 函数在调用时计算该函数的任何 ARGUMENTS。它不会立即评估函数体内的任何值。因此,在延迟操作发生时执行内部分配。
所以:
代码运行
遇到 defer 语句
golang 存储参数值以备后用
延迟函数的主体被完全忽略
其余代码运行到封闭函数的末尾
使用存储的参数值执行延迟函数
-麦克风
青春有我
TA贡献1784条经验 获得超8个赞
很好地回答你自己的问题。我认为值得向未来的读者展示对您最初尝试的更正。
func (t *tss) test() {
if true {
defer func(q int) {
t.q = q //this should evaluate to 't.q = 50' right?
fmt.Println("assigned", t.q, "to t.q")
}(t.q)
t.q = t.m
}
fmt.Printf("q=%v, m=%v\n", t.q, t.m)
}
输出
q=50, m=1
q=1, m=1
assigned 50 to t.q
q=50, m=1
- 2 回答
- 0 关注
- 170 浏览
添加回答
举报
0/150
提交
取消