ゴー1.7ベータ1は、ここでは、今朝リリースさthe release notes draft of Go 1.7ですました。新しい機能KeepAlive
がパッケージruntime
に追加されました。 The doc of runtime.KeepAlive
例を与えている:ファイルディスクリプタ Dを含有する構造体の場合、P点、例えばGoでは、いつ変数に到達できなくなるのですか?
、pはファイナライザを有する:
type File struct { d int } d, err := syscall.Open("/file/path", syscall.O_RDONLY, 0) // ... do something if err != nil ... p := &FILE{d} runtime.SetFinalizer(p, func(p *File) { syscall.Close(p.d) }) var buf [10]byte n, err := syscall.Read(p.d, buf[:]) // Ensure p is not finalized until Read returns. runtime.KeepAlive(p) // No more uses of p after this point.
The doc of
runtime.SetFinalizer
もruntime.KeepAlive
について説明を与えていますそれは、そのファイルディスクリプタを閉じ、関数内のpの 最後の使用はsyscall.Write(PD、bufが、 サイズ)への呼び出しがある場合はすぐにプログラムとしては syscall.Writeに入ると、そしてpは到達できないことがあります。ファイナライザは は、それが閉じられたファイル 記述子への書き込みをされているためsyscall.Writeが失敗し、p.dを閉じて、その時点で実行することができる(または、より悪い、完全に異なるファイルディスクリプタに異なるゴルーチンで をオープンしました)。この問題を回避するには、syscall.Writeを呼び出した後に runtime.KeepAlive(p)を呼び出します。
私は変数p
がまだ生命の範囲を去っていないということを私に混乱させました。なぜそれが到達不能になるのですか?これは、変数がそのライフスコープにあるかどうかに関わらず、次のコードでその変数を使用しないと変数に到達できないことを意味しますか?