Go 对同一个函数的两个defer调用是否同时执行?

Go 对同一个函数的两个defer调用是否同时执行?,go,deferred,deferred-execution,Go,Deferred,Deferred Execution,下面代码中的延迟发生了什么变化 package main import "net/http" func main() { resp, _ := http.Get("http://google.com") defer resp.Body.Close() resp, _ = http.Get("http://stackoverflow.com") defer resp.Body.Close() } 有两

下面代码中的
延迟发生了什么变化

package main

import "net/http"

func main() {
    resp, _ := http.Get("http://google.com")
    defer resp.Body.Close()
    resp, _ = http.Get("http://stackoverflow.com")
    defer resp.Body.Close()
}

有两个HTTP
GET
调用,都返回同一个变量。
defer
stack操作,导致两个
Close()
调用,还是在
main()
完成时只执行一个调用?(如果是后者:这是执行的第一个还是第二个
defer

是的,
defer
确实堆栈了对变量
resp
的引用,导致两个
Close
调用。例如,在以下代码中,使用两个不同的
A
值调用
cleanUp
函数:

package main

import "fmt"

type Resp struct {
    A int
}

func (r *Resp) cleanUp() {
    fmt.Println("Cleaned up ", r.A)
}

func main() {
    r := &Resp{1}   
    defer r.cleanUp()   
    
    fmt.Println("I am doing something here!")

    r = &Resp{2}
    defer r.cleanUp()
}
以上代码输出:

I am doing something here!
Cleaned up  2
Cleaned up  1

因此,即使覆盖了
r
的值,也不会导致覆盖
defer
语句中的变量。

答案通常是:“每次执行“defer”语句时,调用的函数值和参数都会像往常一样计算并重新保存[…]”。在您的示例中,将执行两个延迟调用;将使用每个延迟语句点处的值。这里比较棘手的部分是
resp
resp.Body
是否是一个被第二个
http.Get
覆盖的
struct
,或者它是一个指针,第二个
http.Get
获取一个新的、不同的
resp
resp.Body
。由于http.Get每次都返回一个新指针,因此这样做是正确的。更多信息请参见链接副本。我毫不怀疑两个不同的
defer
语句都将被执行。我的问题是,两者使用相同的
resp
(具有不同的值),因此,如果使用了指针,则只会执行一个指针。它是否为指针并不重要。如果两次使用DEBER,则相应的方法将执行两次。我已更新了上述答案。@SaiRaviTejaK虽然执行两次并不重要,但在这种特殊情况下,它关系到正确性,最后将关闭第二次resp的两倍。请参阅:@WoJ要了解正确性,您需要使用两个不同的resp变量。看看你是否用同样的。