Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.Sign up
proposal: Go 2: Formal Destructors #38057
I'm sure this has been discussed many times before - perhaps more around the desire for
I don't have any proposed syntax or tightly defined semantics, this is more about what
Simply put, the proposal is to be able to attach a formal Destructor (in Java-speak, a
The motivation is to be able to garbage collect resources invisible to the go GC and not
While go isn't particularly designed to directly manipulate underlying OS resources the
Examples within go include os.File, http.Body and the net.*Conn family. Essentially any
Examples outside of go include file system objects such as cache files, named pipes and
More obscure examples include OS resources created by the likes of dup(), Dup2() and
Any package which creates these sort of resources usually wants to offer a way to destroy
I confess that I have noticed SetFinalizer before but have never really looked at it in any depth. But I guess I'm confused as to why packages still offer Close() if SetFinalizer solves their problem? Is it purely historical and no future package should ever offer Close()? If so, I'm a happy camper.
If you want to be careful about avoiding resource leaks, I would recommend using the finalizer to verify that
I was trying to avoid proposing a specific language change as I was more interested in whether the idea of being able to define a destructor was of more general interest beyond my own needs, or not.
But yes, a concrete proposal might make my ramblings clearer.
One implementation might be a SetFinalizer variant which offers more certainty about when the finalizer function gets called. Specifically that the finalizer function gets called as soon as the object becomes unreachable, not at some indeterminate time in the future when the GC happens to notice. More like the semantics of a C++ smart pointer than a Java Finalizer.
One goal is to replicate the typical
Things get a lot trickier when object references are passed around and copied. But semantically this variant finalizer call should occur as soon as all references disappear.
From my limited internals knowledge of go, this seems like it might unfortunately be hard to implement, but I really don't have much of a clue on that front. And frankly it doesn't matter if hardly anyone thinks it's a good idea in the first instance.
But, having objects be able to reliably release resources on their own volition as soon as they can no longer be reached by the application is the over-arching goal.
I am guessing but if we could wave a magic wand and replace all existing Close() calls with SetFinalizer equivalents, that there would be plenty of applications which would blow out resource usage in some way. So go is currently stuck with these bodged up, hand-crafted destructors called Close(). Are we ok with that?
It's very difficult for a garbage collected language to have destructors that take effect as soon as the object becomes unreachable, because there is nothing that tracks whether objects are reachable. The best that a garbage collected language can normally do is run a destructor when the garbage collector discovers that the object is unreachable; that is often called a finalizer, and Go already has finalizers.
Destructors work in languages like C++ because C++ doesn't have garbage collection. Therefore, every object has a lifespan that is precisely controlled by the program, either because the object is a local variable or because it lives until the program explicitly calls