Documentation
¶
Overview ¶
Package opt provides safe abstractions over optional values.
Inspired by the Option type in Rust and follows the same ideas and function signatures.
Index ¶
- type Opt
- func AndThen[T, U any](option Opt[T], f func(T) Opt[U]) Opt[U]
- func FromProto[T proto.Message](msg T) Opt[T]
- func FromPtr[T any](ptr *T) Opt[T]
- func FromZero[T comparable](value T) Opt[T]
- func IndexMap[M ~map[K]V, K comparable, V any](m M, key K) Opt[V]
- func IndexSlice[S ~[]T, T any](slice S, index int) Opt[T]
- func Map[T, U any](option Opt[T], f func(T) U) Opt[U]
- func None[T any]() Opt[T]
- func Some[T any](value T) Opt[T]
- func (o Opt[T]) And(and Opt[T]) Opt[T]
- func (o Opt[T]) AndThen(andThen func(T) Opt[T]) Opt[T]
- func (o Opt[T]) Filter(predicate func(T) bool) Opt[T]
- func (o Opt[T]) GetOr(or T) T
- func (o Opt[T]) GetOrElse(orElse func() T) T
- func (o Opt[T]) GetOrEmpty() T
- func (o *Opt[T]) GobDecode(data []byte) error
- func (o Opt[T]) GobEncode() ([]byte, error)
- func (o Opt[T]) Inspect(f func(T)) Opt[T]
- func (o Opt[T]) IsExplicit() bool
- func (o Opt[T]) IsNone() bool
- func (o Opt[T]) IsNoneOr(orElse func(T) bool) bool
- func (o Opt[T]) IsSome() bool
- func (o Opt[T]) IsSomeAnd(and func(T) bool) bool
- func (o Opt[T]) Map(f func(T) T) Opt[T]
- func (o Opt[T]) MarshalBinary() ([]byte, error)
- func (o Opt[T]) MarshalJSON() ([]byte, error)
- func (o Opt[T]) MarshalText() ([]byte, error)
- func (o Opt[T]) MustGet() T
- func (o Opt[T]) Or(or Opt[T]) Opt[T]
- func (o Opt[T]) OrElse(orElse func() Opt[T]) Opt[T]
- func (o *Opt[T]) Scan(src any) error
- func (o Opt[T]) String() string
- func (o Opt[T]) ToPtr() *T
- func (o Opt[T]) TryGet() (T, bool)
- func (o *Opt[T]) UnmarshalBinary(data []byte) error
- func (o *Opt[T]) UnmarshalJSON(b []byte) error
- func (o *Opt[T]) UnmarshalText(data []byte) error
- func (o Opt[T]) Value() (driver.Value, error)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Opt ¶
type Opt[T any] struct { // contains filtered or unexported fields }
Opt (option) represents an optional value. Every option is either Some and contains a value, or None, and does not.
Opt also separates explicitly set values, see Opt.IsExplicit. Implicit Some is unreachable state.
Use cases:
- Initial values
- Return values for functions that are not defined over their entire input range (partial functions)
- Optional struct fields
- Optional function arguments
func AndThen ¶
AndThen returns None if the option is None, otherwise calls `f` with the wrapped value and returns the result.
This function allows `f` to return a different type in contrast to the Opt.AndThen which is limited by the lack of method type parameters in Go.
Example ¶
firstRune := func(s string) Opt[rune] { runes := []rune(s) if len(runes) == 0 { return None[rune]() } return Some(runes[0]) } fmt.Println(AndThen(Some("яблоко"), firstRune)) fmt.Println(AndThen(Some(""), firstRune)) fmt.Println(AndThen(None[string](), firstRune))
Output: Some(1103) None None
func FromProto ¶
FromProto converts proto.Message to either Some value, if the message is valid, or None.
An invalid message is an empty, read-only value. An invalid message often corresponds to a nil pointer of the concrete message type, but the details are implementation dependent.
See [protoreflect.Message.IsValid]
func FromPtr ¶
FromPtr returns Some with the underlying pointer value if it's not nil or None otherwise.
NOTE: Do not use this for converting [proto.Message]s, as they can not be dereferenced without breaking internal reflection mechanism. Use FromProto for that purpose
Example ¶
value := 42 var x, y *int x = &value y = nil fmt.Println(FromPtr(x)) fmt.Println(FromPtr(y))
Output: Some(42) None
func FromZero ¶
func FromZero[T comparable](value T) Opt[T]
FromZero returns Some with the given value if it's not zero value or None otherwise.
This function requires value type to be comparable so that it can be checked for zero value without using reflection
Example ¶
fmt.Println(FromZero(0)) fmt.Println(FromZero("foo")) fmt.Println(FromZero(""))
Output: None Some(foo) None
func IndexMap ¶
func IndexMap[M ~map[K]V, K comparable, V any](m M, key K) Opt[V]
IndexMap returns Some map value at the given key if the key exists or None otherwise
Example ¶
m := map[string]int{ "a": 1, } fmt.Println(IndexMap(m, "a")) fmt.Println(IndexMap(m, "b"))
Output: Some(1) None
func IndexSlice ¶
IndexSlice returns Some slice value at the given index if the index exists or None otherwise
Example ¶
s := []int{10, 40, 30} fmt.Println(IndexSlice(s, 1)) fmt.Println(IndexSlice(s, 3))
Output: Some(40) None
func Map ¶
Map maps a value by applying a function to a contained value (if Some) or returns None (if None).
This function allows `f` to return a different type in contrast to the Opt.Map which is limited by the lack of method type parameters in Go.
Example ¶
maybeSomeString := Some("Hello, World!") maybeSomeLen := Map(maybeSomeString, func(s string) int { return len(s) }) fmt.Println(maybeSomeLen) x := None[string]() fmt.Println(Map(x, func(s string) int { return len(s) }))
Output: Some(13) None
func None ¶
None returns an option with no value. None option could also be defined like that:
var none Opt[any]
Example ¶
x := None[int]() fmt.Println(x)
Output: None
func Some ¶
Some returns option with some value
Example ¶
x := Some(2) fmt.Println(x)
Output: Some(2)
func (Opt[T]) And ¶
And returns None if the option is None, otherwise returns `and`.
Example ¶
x := Some(2) y := None[int]() fmt.Println(x.And(y)) x = None[int]() y = Some(42) fmt.Println(x.And(y)) x = Some(2) y = Some(42) fmt.Println(x.And(y)) x = None[int]() y = None[int]() fmt.Println(x.And(y))
Output: None None Some(42) None
func (Opt[T]) AndThen ¶
AndThen returns None if the option is None, otherwise calls `andThen` with the wrapped value and returns the result.
See AndThen if you need to return a different type
Example ¶
div42By := func(divider int) Opt[int] { if divider == 0 { return None[int]() } return Some(42 / divider) } fmt.Println(Some(2).AndThen(div42By)) fmt.Println(None[int]().AndThen(div42By)) fmt.Println(Some(0).AndThen(div42By))
Output: Some(21) None None
func (Opt[T]) Filter ¶
Filter returns None if the option is None, otherwise calls predicate with the wrapped value and returns:
Example ¶
isEven := func(n int) bool { return n%2 == 0 } fmt.Println(None[int]().Filter(isEven)) fmt.Println(Some(3).Filter(isEven)) fmt.Println(Some(4).Filter(isEven))
Output: None None Some(4)
func (Opt[T]) GetOr ¶
func (o Opt[T]) GetOr(or T) T
GetOr returns the contained Some value or a provided default.
Example ¶
fmt.Println(Some("car").GetOr("bike")) fmt.Println(None[string]().GetOr("bike"))
Output: car bike
func (Opt[T]) GetOrElse ¶
func (o Opt[T]) GetOrElse(orElse func() T) T
GetOrElse returns the contained Some value or computes it from a function.
Example ¶
k := 10 fmt.Println(Some(4).GetOrElse(func() int { return 2 * k })) fmt.Println(None[int]().GetOrElse(func() int { return 2 * k }))
Output: 4 20
func (Opt[T]) GetOrEmpty ¶
func (o Opt[T]) GetOrEmpty() T
GetOrEmpty returns the contained Some value or an empty value for this type.
Example ¶
x := None[int]() y := Some(12) fmt.Println(x.GetOrEmpty()) fmt.Println(y.GetOrEmpty())
Output: 0 12
func (*Opt[T]) GobDecode ¶
GobDecode implemenets gob.GobDecoder interface
func (Opt[T]) GobEncode ¶
GobEncode implemenets gob.GobEncoder interface
func (Opt[T]) Inspect ¶
Inspect calls a function with a contained value if Some.
Returns the original option.
Example ¶
x := Some("banana") x.Inspect(func(s string) { fmt.Println(s) }) y := None[string]() y.Inspect(func(s string) { fmt.Println(s) })
Output: banana
func (Opt[T]) IsExplicit ¶
IsExplicit reports whether this option was explicitly specified as either None or Some. This property is also applicable for decoded values, such as ones from json.Unmarshal.
If true, it is guaranteed that Opt.IsSome will also return true
This propery allows to represent the following states:
Example ¶
var implicit Opt[string] explicit := None[string]() fmt.Println(implicit, implicit.IsExplicit()) fmt.Println(explicit, explicit.IsExplicit())
Output: None false None true
func (Opt[T]) IsNone ¶
IsNone returns true if the option is a None value.
Example ¶
x := Some(2) fmt.Println(x.IsNone()) x = None[int]() fmt.Println(x.IsNone())
Output: false true
func (Opt[T]) IsNoneOr ¶
IsNoneOr returns true if the option is a None or the value inside of it matches a predicate.
Example ¶
x := Some(2) fmt.Println(x.IsNoneOr(func(x int) bool { return x > 1 })) x = Some(0) fmt.Println(x.IsNoneOr(func(x int) bool { return x > 1 })) x = None[int]() fmt.Println(x.IsNoneOr(func(x int) bool { return x > 1 }))
Output: true false true
func (Opt[T]) IsSome ¶
IsSome returns true if the option is a Some value.
If this option is Some it is guaranteed to be explicit. See Opt.IsExplicit
Example ¶
x := Some(2) fmt.Println(x.IsSome()) x = None[int]() fmt.Println(x.IsSome())
Output: true false
func (Opt[T]) IsSomeAnd ¶
IsSomeAnd returns true if the option is a Some and the value inside of it matches a predicate.
Example ¶
x := Some(2) fmt.Println(x.IsSomeAnd(func(x int) bool { return x > 1 })) x = Some(0) fmt.Println(x.IsSomeAnd(func(x int) bool { return x > 1 })) x = None[int]() fmt.Println(x.IsSomeAnd(func(x int) bool { return x > 1 }))
Output: true false false
func (Opt[T]) Map ¶
Map maps a value by applying a function to a contained value (if Some) or returns None (if None).
See Map if you need to return a different type.
Example ¶
maybeSomeAge := Some(30) maybeSomeYear := maybeSomeAge.Map(func(age int) int { return 2025 - age }) fmt.Println(maybeSomeYear) x := None[int]() fmt.Println(x.Map(func(n int) int { return n * 2 }))
Output: Some(1995) None
func (Opt[T]) MarshalBinary ¶
MarshalBinary implemenets encoding.BinaryMarshaler interface
func (Opt[T]) MarshalJSON ¶
MarshalJSON implemenets json.Marshaler interface
func (Opt[T]) MarshalText ¶
MarshalText implemenets encoding.TextMarshaler interface
func (Opt[T]) MustGet ¶
func (o Opt[T]) MustGet() T
MustGet returns the contained Some value.
Panics if the self value equals None.
func (Opt[T]) Or ¶
Or returns itself if it contains a value, otherwise returns `or`.
Example ¶
x := Some(2) y := None[int]() fmt.Println(x.Or(y)) x = None[int]() y = Some(100) fmt.Println(x.Or(y)) x = Some(2) y = Some(100) fmt.Println(x.Or(y)) x = None[int]() y = None[int]() fmt.Println(x.Or(y))
Output: Some(2) Some(100) Some(2) None
func (Opt[T]) OrElse ¶
OrElse returns itself if it contains a value, otherwise calls `orElse` and returns the result.
Example ¶
nobody := func() Opt[string] { return None[string]() } vikings := func() Opt[string] { return Some("vikings") } fmt.Println(Some("barbarians").OrElse(vikings)) fmt.Println(None[string]().OrElse(vikings)) fmt.Println(None[string]().OrElse(nobody))
Output: Some(barbarians) Some(vikings) None
func (*Opt[T]) Scan ¶
Scan implements the sql.Scanner interface.
func (Opt[T]) ToPtr ¶
func (o Opt[T]) ToPtr() *T
ToPtr returns pointer to the value if the option is Some or nil otherwise.
The underlying value of the pointer is safe to modify, as it is copied before return to avoid changes to the original value.
Example ¶
x := Some(42) y := None[int]() fmt.Println(x.ToPtr() != nil, *x.ToPtr()) fmt.Println(y.ToPtr())
Output: true 42 <nil>
func (Opt[T]) TryGet ¶
TryGet returns the contained Some value or an empty value for this type and boolean stating if this option is Some
If you only need a contained value or an empty one use Opt.GetOrEmpty
Example ¶
x := Some(42) y := None[int]() fmt.Println(x.TryGet()) fmt.Println(y.TryGet())
Output: 42 true 0 false
func (*Opt[T]) UnmarshalBinary ¶
UnmarshalBinary implemenets encoding.BinaryUnmarshaler interface
func (*Opt[T]) UnmarshalJSON ¶
UnmarshalJSON implemenets json.Unmarshaler interface
func (*Opt[T]) UnmarshalText ¶
UnmarshalText implemenets encoding.TextUnmarshaler interface
func (Opt[T]) Value ¶
Value implements the driver.Valuer interface.
Use unwrap methods (e.g. Opt.TryGet) instead for getting the go value