Earlier quoted context omitted.
>and this kind of leak has side effects Only if the calling function does something with the pointer (which it generally won't, if err is non-nil). If the calling code does do something with the pointer even when err is non-nil, then either (a) the value of the pointer is meaningful, and this is fine; or (b) there's a logic error in the calling code, which is a far more serious bug than a potential memory leak. So I…
I should have been more explicit. Go is garbage collected . If you keep a pointer live, then it’s not garbage , which prevents it from being collected. At least Go doesn’t use RAII, so inadvertently pinning a pointer won’t keep a socket open or a lock held.
The following toy example doesn't leak memory. Are you thinking of some other pattern that would leak memory? If so, what is it? I can only think of patterns where a logic error is also involved. That is, where the meaningless value of 'val' is used in code paths where err != nil.
func alwaysError() (*int, error) {
var dummy int
// We return &dummy even though it's a meaningless value.
// Will this cause a memory leak?
return &dummy, fmt.Errorf("An error")
}
func caller() {
val, err := alwaysError()
if err != nil {
fmt.Printf("Error\n")
// It won't! Because the value pointed to by 'val'
// can be GCed from this point on.
return
}
// never get here
fmt.Printf("Value %v\n", val)
//
// ...lots of code that uses *val...
//
}
You might think that you'd get a leak if the error branch was also long-lived, but Go's GC seems to be precise with respect to conditional branching (as far as I can tell by experimenting with runtime.SetFinalizer). That is, as long as the error branch doesn't refer to 'val', then the value pointed to by 'val' can be collected once the error branch is entered (and before 'caller' returns).