4 ms·
func foo() (*SomeType, error) { ... return someErr } ... result, err := foo() if err != nil { // handle err } /
by lenish 6y ago
func foo() (*SomeType, error) {
...
return someErr
}
...
result, err := foo()
if err != nil {
// handle err
}
// handle result
vs
type Result struct {
Err error
Data SomeType
}
func (r *Result) HasError() bool {
return r.Err != nil
}
func bar() *Result {
...
return &Result { ... }
}
...
result := bar()
if result.HasError() {
// handle result.Err
}
// handle result
I'm not really sure I see the benefit to the latter. In a language with special operators and built-in types it may be easier (e.g. foo()?.bar()?.commit()), but without these language features I don't see how the Result<T> approach is better.
- et1337 6y agoGo can't really express the Result<T> approach. In Go, it's up to you to remember to check result.HasError(), just like it's up to you to check if err != nil. If you forget that check, you'll try to access the Data and get a nil pointer exception. The Result<T> approach prevents you from accessing Data if you haven't handled the error, and it does so with a compile-time error. Even with Go's draconian unused variable rules, I and my colleagues have been burned more than once by forgotten error checks.
- jatone 6y agothere are linters that will help you with that. https://github.com/kisielk/errcheck https://github.com/kisielk/errcheck https://golangci-lint.run/usage/linters/ https://golangci-lint.run/usage/linters/ has a solid set of options.
- nimish 6y agoI just wish the linter was integrated into the compiler. And that code that didn't check would simply not compile
- apta 6y agoThe alternative is not the Result type you defined, but something along the lines of what languages like Rust or Haskell define: https://doc.rust-lang.org/std/result/ https://doc.rust-lang.org/std/result/
- whateveracct 6y agoA language with sun types will express Result as Success XOR Failure. And then to access the Success, the compiler will force you to go through a switch statement that handles each case.
- mrkeen 6y ago> without these language features I don't see how the Result<T> approach is better. That's the point! I want language features! I don't want to wait 6 years for the designers to bake some new operator into the language. I want rich enough expression so that if '?.' is missing I just throw it in as a one-liner. Generics is one such source of richness.