一个函数调用可以跟在一个defer关键字后面,成为一个延迟函数调用。
  • 被延迟的函数调用的所有返回值(如果存在)必须全部被舍弃。
  • 当一个延迟调用语句被执行时,其中的延迟函数调用不会立即被执行,而是被推入由当前协程维护的一个延迟调用队列(后进先出)。

    func main() {
      defer fmt.Println("three")
      defer fmt.Println("two")
      fmt.Println("one")
      // 打印
      // one
      // two
      // three
    }
  • 当一个函数调用返回(此时可能尚未完全退出)并进入它的退出阶段后,所有在执行此函数调用的过程中已经被推入延迟调用队列的调用将被按照它们被推入的顺序逆序被弹出队列并执行

    一个延迟调用可以修改包含此延迟调用的最内层函数的返回值

  1. 延迟函数可能操作主函数的具名返回值 (设置返回值,执行defer,返回)
  2. 若返回字面值则无法操作
  3. 匿名返回值返回变量,defer可引用不可改变返回值
  4. 延迟函数的参数在defer语句出现时即确定

    //具名返回值
    func Triple(n int) (r int) {
     defer func() {
         // r = 10
         // n = 5
         r += n // 修改返回值
     }()
    
     return n + n // <=> r = n + n; return
    }
    func main() {
     fmt.Println(Triple(5)) // 15
    }
// 返回字面值
func modifyLiteralReturn() int {
    result := 10
    defer func() {
        result += 5 // 修改局部变量,但不影响返回值
    }()
    return result // 立即返回字面值
}

func main() {
    fmt.Println(modifyLiteralReturn()) // 输出: 10
}
func modifyAnonymousReturn() int {
    result := 10
    defer func() {
        result += 5 // 修改局部变量,但不影响返回值
    }()
    return result // 返回局部变量,defer 无法修改返回值
}

func main() {
    fmt.Println(modifyAnonymousReturn()) // 输出: 10
}
func demonstrateDefer() {
    x := 10
    defer func(val int) {
        fmt.Println("Deferred value:", val) // 10
    }(x)

    x = 20
    fmt.Println("Current value:", x) // 20
}

func main() {
    demonstrateDefer()
}

桃瑾
1 声望1 粉丝

常常播种,有时收获


« 上一篇
go-字符串
下一篇 »
限流算法