在面向对象语言中,我使用类变量来跟踪当前生成的实例数量,方法是在构造时递增并在销毁时递减。
我尝试在go中实现类似的行为:
package entity
type Entity struct {
Name string
}
func New(name string) Entity {
entity := Entity{name}
counter++
return entity
}
var counter int = 0
func (e *Entity) Count() int {
return counter
}
并且这有效,因为我不能通过析构函数递减计数器。
我可以以某种方式模仿对象破坏吗? 如何正确跟踪实例计数?
答案 0 :(得分:9)
您可以像这样使用runtime.SetFinalizer。有关游乐场版本,请参阅here。
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
请注意使用Finalizer的文档
x的终结器计划在x后的任意时间运行 变得无法到达。无法保证终结器能够运行 在程序退出之前,通常它们仅对于有用 在a期间释放与对象关联的非内存资源 长期运行的计划。
答案 1 :(得分:5)
关于终结者,有一个discussion关于golang-nuts。
目前,
所以你必须自己管理你的实例计数。
通常情况下,您没有自己的实例,因此对于许多实际用途(不包括复杂且难以理解的程序的剖析),您可以使用defer
来跟踪生命的终结。你的变量。我不会假装这真的取代了终结者,但它很简单而且经常足够。