For the same structure, Golang behaves differently in defer in for loop

WBOY
Release: 2024-02-06 09:30:11
forward
932 people have browsed it

对于同一结构体,Golang 在 for 循环中 defer 的行为有所不同

Question content

I wrote the following golang code and ran it.

type test struct {
    name string
}

func (t test) hello() {
    fmt.printf("hello, %s\n", t.name)
}

func (t *test) hello2() {
    fmt.printf("pointer: %s\n", t.name)
}

func runt(t test) {
    t.hello()
}

func main() {
    mapt := []test{
        {name: "a"},
        {name: "b"},
        {name: "c"},
    }

    for _, t := range mapt {
        defer t.hello()
        defer t.hello2()
    }
}
Copy after login

Output:

pointer: C
Hello, C
pointer: C
Hello, B
pointer: C
Hello, A
Copy after login

My understanding is that the pointer t will point to "c" after 3 loops, so the three 3 "c"s are used for the "hello2" output. However, delaying the "hello" function call behaves very strangely. It looks like it's retaining the location it points to. (t test) How to affect this?

I'm curious as to what golang compiles this into. Thank you so much!


Correct answer


In the for loop, the parameter of the defer statement is a closure. The closure captures the loop variable t.

For calls using a value receiver, the closure contains a copy of t. For calls using pointer receivers, the closure contains a pointer to t.

Loop variables are rewritten on each iteration (this behavior will change in later versions of the language). Therefore, value receiver closures capture every value, while pointer receiver closures only capture the pointer, so at runtime they use the latest value of that pointer.

The above is the detailed content of For the same structure, Golang behaves differently in defer in for loop. For more information, please follow other related articles on the PHP Chinese website!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!