【问题标题】:Equivalent of java finalize methodjava finalize方法的等价物
【发布时间】:2011-06-05 22:16:15
【问题描述】:

Go 中有没有类似 java finalize 的方法?如果我有一个像

这样的类型结构
    type Foo struct {
        f *os.File
        ....
    }

func (p *Foo) finalize() {
     p.f.close( )           
}

如何确保当 Object 被垃圾回收时,文件被关闭?

【问题讨论】:

    标签: go


    【解决方案1】:

    你也不会在 java 中这样做。在 java 中正确的做法是有一个 finally 块将其关闭在您打开的位置附近的某个位置。

    您可以在 go 中使用类似的模式和 defer 函数来进行清理。例如,如果你这样做(java):

    try {
      open();
      // do stuff
    } finally {
      close();
    }
    

    在 go 中,你会这样做:

    open();
    defer close();
    // do stuff
    

    【讨论】:

    • 请注意,defer f.close() 在 go 中可能会忽略错误。如果您正在写入文件,那么这可能很重要。请参阅此处groups.google.com/d/msg/golang-nuts/GOd-rmqwAME/bPpqFPh9xkkJ,了解如何正确操作。
    • 嗯,当然,但是任何期望垃圾收集器关闭他的文件的人一开始都不太关心可靠性。我通常不关心关闭时的错误,因为我通常没有其他选择。
    【解决方案2】:

    runtime.SetFinalizeriirc。但它被认为是一件坏事,不能保证在程序退出之前运行

    编辑:如下所述,当前的os 包已经在文件上调用runtime.SetFinalizer。但是,不应依赖 SetFinalizer。作为一个例子,我有一个类似文件服务器的应用程序,我忘记关闭打开的文件。在 GC 拾取并调用它们的终结器之前,该过程通常会获得大约 300 个打开的文件。

    【讨论】:

    • 如果你没有显式关闭一个 os.File,它的构造函数调用`runtime.SetFinalizer`,所以当它被 gc'ed 时它无论如何都会被关闭(如上所述可能直到程序退出才会发生) .无需提供您自己的终结器。
    • @Nos 是的,我意识到这一点。我想我应该把它包括在我的答案中,但我在我的手机上。
    • 使用SetFinalizer 确实是一种不好的做法。取而代之的是达斯汀的回答:使用defer 关键字。它是为资源清理而设计的。
    • @Kirakun 我知道,但 defer 与 SetFinalizer 不同。完全没有。而 defer 不是上述问题的答案。
    猜你喜欢
    • 2015-03-13
    • 1970-01-01
    • 2012-06-03
    • 2013-01-15
    • 1970-01-01
    • 2010-11-13
    • 2019-11-03
    • 2011-01-16
    • 1970-01-01
    相关资源
    最近更新 更多