▲ | troupo a day ago | ||||||||||||||||||||||||||||||||||
It's actually very rare that it should be the caller who has to handle the errors. Go, however, forces you to spread your error handling over a thousand little pieces with zero overview or control of what's happening. Rust eventually realised this and introduced try! and ? to simplify this | |||||||||||||||||||||||||||||||||||
▲ | koito17 a day ago | parent | next [-] | ||||||||||||||||||||||||||||||||||
More importantly, Rust has the notion of a result type and it is designed to be both generic and composable. A problem I often face in Go and TypeScript code is code that ignores errors, often unintentionally. For instance, many uses of JSON.parse in TypeScript do not check for the SyntaxError that may be thrown. In Go, it is common to see patterns like
This pattern exists to tell the reader "I don't care if this method returns an error". It allows one to avoid returning an error, but it also stops the caller from ever being handle to the error.Also, the position of the error matters. While the convention in the stdlib is to return errors as the final value, this isn't necessarily followed by third party code. Similarly, errors are just an interface and there is no requirement to actually handle returned errors. Even if one wants to handle errors, it's quite awkward having to use errors.As or errors.Is to look into a (possibly wrapped) chain of errors. The benefit of Rust's Result<T, E> is that - position doesn't matter - there is strong, static type checking - the language provides operators like ? to effortlessly pass errors up the call stack, and - the language provides pattern matching, so it's easy to exhaustively handle errors in a Result The last two points are extremely important. It's what prevents boilerplate like
and it's what allows one to write type-safe code rather than guess whether errors.As() or errors.Is() should be used to handle a returned error. | |||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||
▲ | Yoric a day ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||
> Rust eventually realised this and introduced try! and ? to simplify this That was prototyped around Rust 0.4, so I wouldn't say "eventually" :) | |||||||||||||||||||||||||||||||||||
▲ | liotier a day ago | parent | prev [-] | ||||||||||||||||||||||||||||||||||
Unsure if this is the right place to ask, but this conversation inspires me this question: Is there in practice a significant difference between try/catch and Go's "if err" ? Both seem to achieve the same purpose, though try/catch can cover a whole bunch of logic rather than a single function. Is that the only difference ? | |||||||||||||||||||||||||||||||||||
|