3 ms·
So instead of writing x, err := something() if err != nil { handleError(err) } n, err := somethingElse(x) if err != nil { handleError(err
by dchest 14y ago
So instead of writing
x, err := something()
if err != nil {
handleError(err)
}
n, err := somethingElse(x)
if err != nil {
handleError(err)
}
andSoOn()
you could write
switch x := something() {
case error:
handleError(err)
case string:
switch n := somethingElse(x) {
case error:
handleError(n)
case int:
andSoOn()
}
}
?
- lmm 14y agoYes. The advantage of the second form is that x := something() n := somethingElse(x) andSoOn() no longer compiles. Obviously you would also want some syntactic sugar to make it look nice, but that's quite simple.
- masklinn 14y agoThere's also the option of doing it on an explicitly tagged union, Erlang-style: `something` returns not `Value` or `Either(Error, Value)` but `{ok, Value} | {error, Reason}`. This means you can handle the error: case something() of {ok, Value} -> %%; {error, Reason} -> %% end or you can "ignore" it {ok, Value} = something() but (and this is important) the latter *will not pass silently if `something()` returns an error. Instead, it will raise a "BadMatch" fault, similar to an Haskell-ish let (Right value) = something() where `something :: Either a b`
- dchest 14y agox := something() n := somethingElse(x) andSoOn() This won't compile in Go. x, err := something() n, err := somethingElse(x) andSoOn() This won't compile in Go as well (compiler requires that you use the variables you declare). You can only explicitly ignore errors: x, _ := something() n, _ := somethingElse(x) andSoOn() Except for one case where error is the only returned value. err := fmt.Println("") _ = fmt.Println("") // ok fmt.Println("") // ok