This is simply false and a misconception held by people who haven't spent a lot of time with the language. You not only can, but absolutely SHOULD handle errors in defers.
Using named return parameters on your method, your error return is still in scope and can be set. This is how you properly handle errors on defers.
If you've spent a lot of time with the language, then you've surely noticed that people rarely do this (because it's extremely verbose). The language encourages ignoring errors in defer.
(Contrary to the parent post, I'm not sure this is a real problem, however.)
Error handling should not require l33t features. (This is my big argument with both Go and Rust. The stuff they use to get around not having exceptions is worse than exceptions.)
Exceptions are absolutely a "l33t feature". They break whatever is currently happening. They are an uncontrolled return working its way up your structure.
While you're attempting to recover from that Exception I gracefully catch my error and can even use the multiple return values that came back successfully from my function, despite there being an error.
Edit: your example works too, though I find it weird...
func Foo() (err error) { defer func() { err = errors.New("some error") }() }
The function will return the "some error" error.
However, checking the return value is always a good idea, and any errors should at least be logged.
I too wish it was less cumbersome to use defer properly.
Languages where closures capture by value (ML, Haskell) or where the programmer explicitly chooses between capturing by value and by reference (C++, Rust) are free of these complications.
https://play.golang.org/p/zyMbmJsnUz // minor mod of donatj's example.
But for correctness, yeah, you just don't have to think about it. So you don't think "by value" or "by reference", it just becomes something obvious that you don't need to think about.
Oh, right.
with<T>(resource : T, body : T => Void) where T <: Resource
with(file, f => { ... })You don't need many control constructs, and the list is pretty well known, so you may as well design them into the language.
"Defer" was probably a bad idea. It's a run-time construct - you're adding to a to-do list run at the end of the function. It's not scope oriented. Something like Python's "with" clause would have been both simpler and more useful. "with" calls "_enter" on an object when you enter a scope, and "_exit" when you leave, no matter how you leave. All the file-like and lock-like objects support "with". Python's "with" even supports exceptions properly - if you're handling an exception when "_exit" is called, the "_exit" function gets told about the exception, so it can clean up and then re-raise the exception. If an "_exit" itself needs to raise an exception, that works, too.
"Defer" is blind. With "defer", nobody ever finds out that the close failed to write the end of the file.