Go java finalize方法的等价物

Go java finalize方法的等价物,go,Go,Go中是否有类似java finalize的方法?如果我有一个像 type Foo struct { f *os.File .... } func (p *Foo) finalize() { p.f.close( ) } 如何确保当对象被垃圾收集时,文件已关闭?runtime.SetFinalizeriirc。但它被认为是一件坏事,不能保证在程序退出之前运行 编辑:如下所述,当前的os包已经对文件调用了runti

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

    type Foo struct {
        f *os.File
        ....
    }

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

如何确保当对象被垃圾收集时,文件已关闭?

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


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

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

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

在go中,您将执行以下操作:

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

如果您没有显式关闭os.File,它的构造函数将调用'runtime.SetFinalizer',因此它在gc'启动时将被关闭(如前所述,在程序退出之前可能不会发生这种情况)。没有必要提供您自己的终结器。@不,是的,我知道。我想我应该把它包括在我的答案中,但我正在打电话。使用
SetFinalizer
确实是一种不好的做法。取而代之的是达斯汀的答案:使用
defer
关键字。它是为资源清理而设计的。@Kirakun我知道,但defer与SetFinalizer不同。完全而defer不是上述问题的答案。请注意,go中的
defer f.close()
可能会忽略错误。如果您正在写入文件,那么这可能很重要。请看这里,了解如何正确地执行此操作。好吧,当然可以,但是任何希望垃圾收集器关闭其文件的人一开始并不太关心可靠性。我通常不关心关闭时的错误,因为我通常没有其他选择。
open();
defer close();
// do stuff