In object oriented languages I use class variables to track how many instances are currently spawned by incrementing on construction and decrementing on destruction.
I try to implement similar behaviour in 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
}
and that works half way as I can not decrement the counter via a destructor.
Can I somehow mimic object destruction? How would I keep track of instance count correctly?
You can use dir() function, which returns all properties and functions in the current script, to count the numbers of instances of a certain class.
By putting the static variable with an increment operator in the constructor method, we can increment the value by 1 each time the constructor is called (when a new object is created). This allows us to keep track of the number of objects that have been created for a class.
You can use runtime.SetFinalizer like this. See here for playground version.
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)
}
This prints
Entities 1 {Sausage}
Entities 2 {Potato}
Entities 0
Entities 1
Entities 0
Note this from the docs for gotchas with Finalizers
The finalizer for x is scheduled to run at some arbitrary time after x becomes unreachable. There is no guarantee that finalizers will run before a program exits, so typically they are useful only for releasing non-memory resources associated with an object during a long-running program.
There was a discussion on golang-nuts about finalizers.
For now,
So you have to manage your instance count yourself.
Usually, you don't have instances living on themselves, so for many practical uses (not including the profiling of a complex and hard to understand program), you can use defer
to track the end of life of your variables. I won't pretend this really replaces finalizers but it's simple and often sufficient.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With