在 godoc( https://blog.golang.org/defer-panic-and-recover ) 中有一个例子:


func c() (i int) {
    defer func() { i++ }()
    return i
}

我还写了一个小程序:
package main

import "fmt"

func b() int {
    i := 0
    for ; i < 4; i++ {
        defer func() {fmt.Println(i); i++} ()
    }
    return i
}
func main() {
  fmt.Println("result = ", b())
}

输出是:
4
5
6
7
result =  4

所以我很困惑,为什么第二个例子不输出 8

最佳答案

请注意“可以读取并分配给返回函数的 命名返回值 ”的部分。

这意味着:

func b() int {
    var i int
    defer func() { fmt.Println(i); i++ }()
    return i
}

会说 0result = 0 ,而:
func b() (i int) {
    defer func() { fmt.Println(i); i++ }()
    return i
}

会说 0result = 1

想象一下,我的第一个示例中的 return ii 值分配给一个隐藏的返回变量(因为它没有命名),然后继续执行 defer 语句(它只修改局部变量 i ),而在第二个示例中例如,我们直接分配给返回变量(因为它已命名),因此 defer 语句可以更改它。

基本上你的程序可以这样解释:
package main

import "fmt"

func b() (hiddenVariable int) {
    i := 0
    for ; i < 4; i++ {
        defer func() { fmt.Println(i); i++ }()
    }
    hiddenVariable = i; return // implicit meaning of return i
}

func main() {
    fmt.Println("result = ", b())
}

关于go - 如何理解go语言中的 `defer`?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40755315/

10-12 05:34