go - 为什么 defer 对周围函数中定义的变量的行为与命名结果不同?

标签 go

下面的程序返回

<nil>
hello

我原以为两者都会返回“hello”,但事实并非如此。我发现该行为是在语言 spec 中作为示例给出的.

For instance, if the deferred function is a function literal and the surrounding function has named result parameters that are in scope within the literal, the deferred function may access and modify the result parameters before they are returned.

我的问题是:为什么 defer 对周围函数中定义的变量的处理方式与对命名结果的处理方式不同?不就是在周围函数返回之前执行的闭包吗?

package main

import (
    "errors"
    "fmt"
)

func main() {

    fmt.Println(up())
    fmt.Println(up2())

}

func up() error {
    var err error
    defer func() {
        err = errors.New("hello")
    }()
    return err
}

func up2() (err error) {
    defer func() {
        err = errors.New("hello")
    }()
    return err
}

func up3() error {
    var err error
    fn := func() {
        err = errors.New("hello")
    }
    fn()
    return err
}

最佳答案

spec says :

A "defer" statement invokes a function whose execution is deferred to the moment the surrounding function returns, either because the surrounding function executed a return statement, reached the end of its function body, or because the corresponding goroutine is panicking.

一个关键点是deferred函数是在return语句执行完之后执行的。

spec also says :

A "return" statement in a function F terminates the execution of F, and optionally provides one or more result values. Any functions deferred by F are executed before F returns to its caller.

up 函数返回 nil,因为延迟函数在 return 语句提供函数结果后设置了 err

up2 函数覆盖返回语句设置的结果值。

关于go - 为什么 defer 对周围函数中定义的变量的行为与命名结果不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43478834/

相关文章:

json - 在 Golang 中反序列化模式字段

unit-testing - 如何对修改发送消息的 net.Conn 函数进行单元测试?

go - 如何在导入包时在 GOPATH 中搜索包?

jquery - 戈朗 : Extracting XML Issue

go - Go 中当前正在运行的进程列表

mongodb - 无法在gin中使用mgo将表单数据插入数据库

arrays - channel 元素类型太大 Golang

戈朗 : index efficiency of array

json - 我如何解码 JSON?

go - 具有对象映射的Avro模式?