icz*_*cza 9

Go团队之前讨论过这个问题,结论并不是为了增加对它的支持.引用minux:

就个人而言,我更喜欢程序退出处理与程序崩溃完全相同的样式.我相信无论你怎么努力,你的程序仍然会在一些不可预见的情况下崩溃; 例如,内存不足会导致任何表现良好的Go程序崩溃,而你无能为力; 所以最好为他们设计.如果你遵循这个,你就不会觉得需要atexit来清理(因为当你的程序崩溃时,atexit将不起作用,所以你根本不能依赖它).

但是你还有一些选择:

处理 CTRL+C

如果你想在程序被CTRL+C(SIGINT)终止时做某事,你可以这样做,参见:

Golang:是否有可能以"延迟"的方式捕获Ctrl + C信号并运行清理功能?

对象终结器

另请注意,您可以为指针值注册终结器函数.当垃圾收集器找到具有关联终结器的无法访问的块时,它会清除关联并f(x)在单独的goroutine中运行.

您可以注册这样的终结器runtime.SetFinalizer(),但是请注意:

无法保证终结器将在程序退出之前运行,因此通常它们仅用于在长时间运行的程序期间释放与对象关联的非内存资源.

看这个例子:

type Person struct {
    Name string
    Age  int
}

func main() {
    go func() {
        p := &Person{"Bob", 20}
        runtime.SetFinalizer(p, func(p2 *Person) {
            log.Println("Finalizing", p2)
        })
        runtime.GC()
    }()

    time.Sleep(time.Second * 1)
    log.Println("Done")
}
Run Code Online (Sandbox Code Playgroud)

输出(Go Playground):

2009/11/10 23:00:00 Finalizing &{Bob 20}
2009/11/10 23:00:01 Done
Run Code Online (Sandbox Code Playgroud)

  • 我还补充说,创建一个需要"atexit"钩子的包是一个糟糕的设计.该软件包应该只导出用户必须显式初始化并显式取消初始化的"内容",然后让用户执行该操作 - 当它真正需要时. (2认同)