Go 中变量何时变得不可访问?
在 Go 中,当运行时确定不可能访问时,变量将变得不可访问。程序再次引用它。即使变量尚未离开其声明的范围,也会发生这种情况。
理解示例
考虑您提供的示例:
type File struct { d int } d, err := syscall.Open("/file/path", syscall.O_RDONLY, 0) p := &FILE{d} runtime.SetFinalizer(p, func(p *File) { syscall.Close(p.d) })
p 变量指向包含文件描述符的结构。终结器附加到 p 以在 p 变得无法访问时关闭文件描述符。然而,Go 代码中最后一次使用 p 是在将其传递给 syscall.Read() 时。
为什么 p 变得无法访问
syscall.Read 的实现() 可以在调用发起后访问文件描述符。这意味着 p 在 Go 代码之外使用,这允许运行时将其标记为不可访问。即使 p 尚未离开其作用域,它也不再存在于 Go 代码库中。
runtime.KeepAlive()
为了防止这种过早标记p 无法访问,您可以使用runtime.KeepAlive(),如示例中所示:
runtime.KeepAlive(p)
通过在此函数调用中引用 p,指示运行时使其保持活动状态,直到 syscall.Read() 返回。这确保了文件描述符在系统调用期间保持有效。
结论
在 Go 中,当变量不再在系统调用中被引用时,它可能会变得不可访问。程序的代码并且正在外部使用,即使它尚未离开其声明的范围。 runtime.KeepAlive() 提供了一种清晰有效的方法来防止变量过早变得不可访问,确保终结器的正确执行并避免意外行为。
以上是Go 变量何时变得无法访问(即使在其作用域内)?的详细内容。更多信息请关注PHP中文网其他相关文章!