Optional values for Go. Inspired by the Rust implementation.
I created this to provide greater coherency of optional handling across the language. In sql, we use NullType
, in json and encoding friends we use pointers, and elsewhere we use ok
. This package adds a more coherent optional experience across the language and is well tested.
Highly tested and aims at high utility. Attempts to follow a monadic design where if the wrapped type T
implements some interface, so should Option[T]
. The following are implemented:
json.Marshaler
json.Unmarshaler
fmt.Stringer
fmt.GoStringer
sql.Scanner
sql.driver.Valuer
If there are any more interfaces which should be wrapped, please open an issue or a PR. All features must be tested.
To declare a present optional value do:
myOption := Some[int](3)
To declare an empty optional value do:
empty := None[int]()
The default value for an Option[T]
is None[T]()
:
var maybeInt Option[int]
if !maybeInt.Ok() {
fmt.Println("The value isn't present!") // This will print, maybeInt hasn't been set.
}
To check if an optional value is present do:
opt := functionReturningOption()
if opt.Ok() {
fmt.Println(opt.Unwrap())
}
To convert a pointer into an optional value do:
var pointer *int
myOption := FromRef(pointer) // Empty for nil pointers
To move values in and out of a sql database do:
db.Exec(`
INSERT INTO test (optional_field) VALUES ($1);
`, Some[int](0))
rows, err := db.Query(`
SELECT * FROM test;
`)
for rows.Next() {
var opt Option[int]
rows.Scan(&opt)
fmt.Println(opt)
}
type MyStruct struct {
Foo Option[int]
}
var v MyStruct
json.Unmarshal([]byte(`{}`), &v)
if v.Foo.Ok() {
fmt.Println(v.Foo.Unwrap())
}