Skip to content

Instantly share code, notes, and snippets.

@RaphGL
Last active September 20, 2023 18:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RaphGL/26424052b6d281ec1656bfa3fd3d0b9f to your computer and use it in GitHub Desktop.
Save RaphGL/26424052b6d281ec1656bfa3fd3d0b9f to your computer and use it in GitHub Desktop.
Rust's API for error handling in Go
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)
}
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)
}
@RaphGL
Copy link
Author

RaphGL commented Jan 4, 2023

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 like Opt[T] and Res[T] (following Go's liking for brevity) that implemented some sort of interface ErrorHandle 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 that nil becomes an internal implementation of functions and data types, increasing null safety and making Go's error handling much much nicer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment