The GC is ubiquitous, and definitely a point in favor for go for the vast majority of use cases, but I've found it more difficult than anticipated to write go code that manipulates resources other than memory that the environment you're running in won't clean up for you. And that's coming from C++ code originally including the exception safety issues.
Also defer() will run even if there is a panic.
This is a direct result of Go's lacking error handling, and would not be necessary if they'd have learned from C++ and Java's mistakes, instead of just repeating them.
Even the Go standard library itself panics (and recovers) when you try to e.g. json-encode a NaN, which doesn't seem like something that should make the system unstable.
func Foo() error {
m.Lock()
defer m.Unlock()
return fooWithLockHeld()
}
But your less experienced colleague was told by Rob Pike himself that the language doesn't have exceptions, so writes: func Foo() error {
m.Lock()
err := fooWithLockHeld()
m.Unlock()
return err
}
That code is not exception safe. It may be a contrived example, but in code review I've many times seen real code that is not exception safe, for basically the same reason.A held lock is fairly benign (only causes a deadlock, not corrupted data) if the net/http.Server swallows it in your handler, or fmt.Print swallows it. But some other errors are not as benign.