以下对象默认情况下会被终结:
os.File
:当对象被垃圾回收时,文件会自动关闭。
os.Process
:终结将释放与进程相关的任何资源。在Unix上,这是一个无操作。在Windows上,它会关闭与进程关联的句柄。
在Windows上,似乎net
包可以自动关闭网络连接。
除了上述提到的对象类型之外,Go标准库不会为其他对象类型设置终结器。
在实际程序中,似乎只有一个潜在的问题可能会导致问题:当 os.File
被终止时,它将调用操作系统来关闭文件描述符。如果 os.File
是通过调用函数 os.NewFile(fd int, name string) *File
创建的,并且文件描述符也被另一个(不同的)os.File
使用,则垃圾回收任何一个文件对象都将使另一个文件对象无法使用。例如:
package main
import (
"fmt"
"os"
"runtime"
)
func open() {
os.NewFile(1, "stdout")
}
func main() {
open()
// Force finalization of unreachable objects
_ = make([]byte, 1e7)
runtime.GC()
_, err := fmt.Println("some text") // Print something via os.Stdout
if err != nil {
fmt.Fprintln(os.Stderr, "could not print the text")
}
}
打印:
could not print the text
some text
。 - zzzz只需查看os.NewFile的源代码:
// NewFile returns a new File with the given file descriptor and name.
func NewFile(fd uintptr, name string) *File {
fdi := int(fd)
if fdi < 0 {
return nil
}
f := &File{&file{fd: fdi, name: name}}
runtime.SetFinalizer(f.file, (*file).close) // <<<<<<<<<<<<<<
return f
}
默认情况下哪些对象会被完成?
在Go中,我认为没有任何东西被默认完成。
默认情况下完成这些对象会导致哪些意外缺陷?
根据上述情况:没有。
runtime.SetFinalizer
文档中列出的许多警告。您永远不应该依赖于或期望最终器被执行。相反,始终确保调用适当的清理函数(例如,在检查os.Open
的错误后立即使用defer file.Close()
)。 - Dave C