Last active
September 20, 2023 18:50
-
-
Save RaphGL/26424052b6d281ec1656bfa3fd3d0b9f to your computer and use it in GitHub Desktop.
Rust's API for error handling in Go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"github.com/raphgl/rufero" | |
"errors" | |
) | |
func returnError() rufero.Result[string] { | |
return rufero.NewResult("", errors.New("this should fail")) | |
} | |
func returnOk() rufero.Result[float32] { | |
return rufero.NewResult[float32](3.14, nil) | |
} | |
func main() { | |
shouldFail := returnError().UnwrapOr("default string") | |
fmt.Println(shouldFail) | |
succeeds := returnOk().Unwrap() | |
fmt.Println(succeeds) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"errors" | |
"fmt" | |
) | |
type Result[T any] struct { | |
value T | |
err error | |
} | |
func NewResult[T any](val T, err error) Result[T] { | |
return Result[T]{ | |
value: val, | |
err: err, | |
} | |
} | |
func (r Result[T]) GetError() error { | |
return r.err | |
} | |
func (r Result[T]) IsOk() bool { | |
return r.err == nil | |
} | |
func (r Result[T]) IsErr() bool { | |
return r.err != nil | |
} | |
func (r Result[T]) Unwrap() T { | |
if r.err == nil { | |
return r.value | |
} else { | |
panic(r.err.Error()) | |
} | |
} | |
func (r Result[T]) UnwrapErr() error { | |
if r.err != nil { | |
return r.err | |
} else { | |
panic(r.value) | |
} | |
} | |
func (r Result[T]) UnwrapOr(defaultValue T) T { | |
if r.err == nil { | |
return r.value | |
} else { | |
return defaultValue | |
} | |
} | |
func (r Result[T]) UnwrapOrElse(fn func(error) T) T { | |
if r.err == nil { | |
return r.value | |
} else { | |
return fn(r.err) | |
} | |
} | |
func (r Result[T]) UnwrapOrDefault() T { | |
if r.err == nil { | |
return r.value | |
} else { | |
var zeroValue T | |
return zeroValue | |
} | |
} | |
func (r Result[T]) Expect(msg string) T { | |
if r.err == nil { | |
return r.value | |
} else { | |
panic(msg) | |
} | |
} | |
func (r Result[T]) ExpectErr(msg string) error { | |
if r.err != nil { | |
return r.err | |
} else { | |
panic(msg) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A very small set of functions that leverage Go's new generics capabilities to provide Rust-like error handling in Go.
The proposals I've seen so far of how they should be haven't been to my liking, so I wrote this just to get a feel for how it would feel like to have rust-like error handling in Go.
The next step after this would be to create an Error container (similar to what
error
does). Something likeOpt[T]
andRes[T]
(following Go's liking for brevity) that implemented some sort of interfaceErrorHandle
that would make it's internal implementation opaque thus forcing the user to handle errors through its own methods to be able to unpack the desired output. This would make so thatnil
becomes an internal implementation of functions and data types, increasing null safety and making Go's error handling much much nicer.