こういうやつ
type Closer struct{ Value string } func (c *Closer) Close(id string) { fmt.Printf("Closed(%s): %p\n", id, c) } func newCloser(c *Closer) { n := &Closer{Value: "aaa"} fmt.Printf("New: %p\n", n) c = n } func main() { c := &Closer{Value: "bbb"} fmt.Printf("Main: %p\n", c) defer c.Close("main") // <-- ここのcはnewCloserで作られたCloserのポインタになっているはず...? newCloser(c) }
上記を実行するとこうなる
Main: 0xc000010240 New: 0xc000010250 Closed(main): 0xc000010240
newCloser関数の内部で参照渡しとしてリソースを上書きしたとしてもmainの中のdefer節で呼ばれるCloseメソッドの呼び出し対象の変数cの参照は古いままなので、newCloser関数の中で作られた方のリソースのクローズ漏れが起きる可能性がある。
これを防ぐためにはnewCloser関数のなかでもdeferでリソースのクローズをするしかない。