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

时间:2017-04-18 17:39:06

标签: go

以下程序返回

<nil>
hello

我希望他们两个回归&#34;你好&#34;但事实并非如此。我发现行为是以spec语言为例。

  

例如,如果延迟函数是函数文字,并且周围函数已命名结果参数在文字范围内,则延迟函数可以在返回之前访问和修改结果参数。

我的问题是:为什么延迟对周围函数中定义的变量的作用与对命名结果的作用不同?它不仅仅是在周围函数返回之前执行的闭包吗?

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
}

1 个答案:

答案 0 :(得分:2)

spec says

  

A&#34;推迟&#34;语句调用一个函数,其执行被推迟到周围函数返回的那一刻,因为周围的函数执行了一个return语句,到达了它的函数体的末尾,或者因为相应的goroutine是恐慌。

关键是在执行return语句后执行延迟函数。

spec also says

  

A&#34;返回&#34;函数F中的语句终止F的执行,并可选地提供一个或多个结果值。在F返回其调用者之前执行F推迟的任何函数。

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

函数up2会覆盖return语句设置的结果值。