golang defer 未按预期进行评估

因此,根据规范,在调用 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=1

q=1, m=1

assigned 50 to t.q

q=50, m=1

但实际输出是:


q=50, m=1

q=1, m=1

assigned 1 to t.q

q=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)

}


qq_遁去的一_1
浏览 171回答 2
2回答

一只甜甜圈

所以我在校对我的帖子时回答了我自己的问题。与其删除它以掩饰我的尴尬,不如将其保留,以防其他人遭受同样的困惑。deferred 函数在调用时计算该函数的任何 ARGUMENTS。它不会立即评估函数体内的任何值。因此,在延迟操作发生时执行内部分配。所以:代码运行遇到 defer 语句golang 存储参数值以备后用延迟函数的主体被完全忽略其余代码运行到封闭函数的末尾使用存储的参数值执行延迟函数-麦克风

青春有我

很好地回答你自己的问题。我认为值得向未来的读者展示对您最初尝试的更正。func (t *tss) test() {&nbsp; &nbsp; if true {&nbsp; &nbsp; &nbsp; &nbsp; defer func(q int) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; t.q = q //this should evaluate to 't.q = 50' right?&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("assigned", t.q, "to t.q")&nbsp; &nbsp; &nbsp; &nbsp; }(t.q)&nbsp; &nbsp; &nbsp; &nbsp; t.q = t.m&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Printf("q=%v, m=%v\n", t.q, t.m)}输出q=50, m=1q=1, m=1assigned 50 to t.qq=50, m=1
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go