このようにruntime.SetFinalizerを使用できます。遊び場バージョンについては、こちらをご覧ください。
package main
import (
"fmt"
"runtime"
)
type Entity struct {
Name string
}
var counter int = 0
func New(name string) Entity {
entity := Entity{name}
counter++
runtime.SetFinalizer(&entity, func(_ *Entity) {
counter--
})
return entity
}
func (e *Entity) Count() int {
return counter
}
func main() {
e := New("Sausage")
fmt.Println("Entities", counter, e)
e = New("Potato")
fmt.Println("Entities", counter, e)
runtime.GC()
fmt.Println("Entities", counter)
e = New("Leek")
fmt.Println("Entities", counter)
runtime.GC()
fmt.Println("Entities", counter)
}
このプリント
Entities 1 {Sausage}
Entities 2 {Potato}
Entities 0
Entities 1
Entities 0
Finalizersを使用した落とし穴のドキュメントからこれに注意してください
xのファイナライザーは、xが到達不能になった後の任意の時間に実行されるようにスケジュールされています。ファイナライザーは、プログラムが終了する前に実行される保証はありません。したがって、通常、ファイナライザーは、長時間実行されるプログラム中にオブジェクトに関連付けられた非メモリーリソースを解放する場合にのみ役立ちます。