轨道 · 写下来的字

go defer

2021.01.07

目录
  1. 函数示例
  2. 输出:
  3. 解释说明

go defer 命名和匿名返回值函数中的返回结果不同

函数示例

package main

import "fmt"

func f1() int {
    var res int
    defer func() {
        res++
    }()
    return res
}

func f2() (res int){
    defer func() {
        res++
    }()
    return res
}

func f3() (res int) {
    defer func() {
        res++
    }()
    return 1
}

func f4() (res int) {
    defer func() {
        res++
    }()
    res = 1
    return res
}

func main() {
    x := f1()
    y := f2()
    z := f3()
    zz := f4()
    fmt.Println("x: ", x, "y: ", y, "z: ", z, "zz: ", zz)
}

输出:

x:  0 y:  1 z:  2 zz:  2

解释说明

这里以匿名返回函数f1()作说明,执行过程如下: 首先函数返回时会自动创建一个返回变量假设为ret,函数返回时要将res赋值给ret,即有ret = res,也就是说ret=0 然后检查函数中是否有defer存在,若有则执行defer中部分,此时就到了res++ 最后返回ret 从上面过程可以看到,函数返回的是ret,即0,虽然defer中res++但是是给res做加减,res和ret是两个变量;

但是在命名返回值f2()中就会有不一样的结果,因为返回值在函数定义时以经存在,return时不需要再创建另外的变量ret,返回的ret就是res,只有一个变量,所以res++就是给实际返回的ret做加减,最终返回结果当然是1了。

f3() 等同于 f4()

defer在命名和匿名返回函数中表现不一样,这是一个很大的坑,使用中要多多注意。

← 回到文章