【Go】defer和os.Exit()

点击阅读更多查看文章内容

特性

  1. 延迟执行defer 语句会将函数调用压入一个栈中,在当前函数返回之前按照 ​后进先出(LIFO)​​ 的顺序执行。

  2. 参数预计算defer 语句中的函数参数会在 defer 语句执行时立即计算,而不是在延迟调用时计算。

    1
    2
    3
    4
    5
    6
    7
    8
    func main() {
    i := 1
    defer fmt.Println("Deferred call:", i)
    i++
    fmt.Println("Main function:", i)
    }
    // Main function: 2
    // Deferred call: 1
  3. 作用域defer 语句的作用域是当前函数,函数返回时才会执行 defer 语句。

  4. 如果函数中有多个 defer 语句,它们会按照 ​后进先出(LIFO)​​ 的顺序执行。

  5. panic后的defer不会被执行,panic之前的defer会被执行(遇到panic,如果没有捕获错误,函数会立刻终止)

  6. panic没有被recover时,抛出的panic到当前goroutine最上层函数时,最上层程序直接异常终止

  7. defer、return、返回值三者的执行逻辑应该是:return最先执行,return负责将结果写入返回值中;接着defer开始执行一些收尾工作;最后函数携带当前返回值退出

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    func testd() int {
    i := 1
    defer func() {
    i++
    }()
    return i
    }

    func main() {
    fmt.Println(testd())
    }
    // 1

defer和os.Exit

问题:在使用os.Exit退出后,defer func() {…}()没有执行

image-20241205204106562

原因:os.Exit函数描述如上,不会执行deferred functions


defer func 与 defer 的参数计算时间

1
2
3
4
5
6
7
8
func test() {
defer func() {
fmt.Println("t1:", time.Now())
}()
defer fmt.Println("t2:", time.Now())
time.Sleep(3 * time.Second)
return
}

执行结果:

t2是声明defer的时间,go会在注册时立即获取time.now的值

t1是返回的时间,函数会在实际执行时才求值

1
2
t2: 2025-04-16 17:28:36.905449 +0800 CST m=+0.000054460
t1: 2025-04-16 17:28:39.907329 +0800 CST m=+3.001915918
作者

ShiHaonan

发布于

2025-03-03

更新于

2025-04-22

许可协议

评论