go - 当 defer func 评估其参数时

标签 go error-handling deferred

我正在学习 defer 在 golang 中的行为方式,并希望在函数返回时使用它来处理错误。

代码如下:

package main

import "fmt"
import "errors"

func main() {
    a()
}

func a() {
    var err error   
    defer func(){
        if err != nil {
            fmt.Printf("1st defer: %s\n", err)
        } else {
            fmt.Println("1st defer: defer not error")
        }
    }()
    defer func(err error){
        if err != nil {
            fmt.Printf("2nd defer: %s\n", err)
        } else {
            fmt.Println("2nd defer: defer not error")
        }
    }(err)

    err = errors.New("new error")
    if err != nil {
        return
    }
}

输出:

2nd defer: defer not error
1st defer: new error

Doc说在评估延迟调用时评估参数,这似乎应该是一致的。为什么 2 defer 对变量 err 有不同的值,从而产生不同的输出?我知道它与第二个函数有 err 作为输入参数有关,但不知道为什么。

最佳答案

好吧,我刚刚想通了。如果您将任何参数传递给延迟函数(如上面的第二个延迟函数),这些参数将在延迟函数被延迟时计算,而不是在它们被执行时计算。这意味着在我的示例中 err 仍然是 nil 并且尚未分配给新错误。

另一方面,在上面的第一个defer中,err不是参数,而是函数a中的一个变量,当第一个defer执行时,它已经被分配给一个新的错误。

关于go - 当 defer func 评估其参数时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42703707/

相关文章:

http - 静态目录未得到服务

go - 将大型结构的 const 指针传递给函数或 go channel

python - “Rect argument is invalid”

jquery - 当用户点击刷新时处理ajax错误

JQuery - 延迟对象数组的 $.when 语法

Go net.DialUDP 自动选择环回接口(interface)

go - golang-tcpclient当我发送http请求时,它总是返回(错误请求400)

javascript - 如何在JavaScript中实现异步函数之间的依赖?

design-patterns - 您想在哪里捕捉异常,为什么?

javascript - Promise.defer 的正确模式是什么?