Documentation
¶
Overview ¶
Package opt provides a generic optional type for Go.
An option represents a value that may or may not be present, providing a type-safe alternative to nil pointers or sentinel values.
Basic usage:
name := opt.Some("Alice")
missing := opt.None[string]()
// Access with comma-ok idiom
if v, ok := name.Get(); ok {
fmt.Println(v)
}
// Or use default values
fmt.Println(missing.OrElse("unknown"))
Options integrate with JSON (marshals to null when empty) and database/sql.
Index ¶
- type Bool
- type Byte
- type Complex128
- type Complex64
- type Error
- type Float32
- type Float64
- type Int
- type Int16
- type Int32
- type Int64
- type Int8
- type Rune
- type String
- type T
- func (t T[V]) All() iter.Seq[V]
- func (t T[V]) Filter(predicate func(V) bool) T[V]
- func (t T[V]) Generate(rand *rand.Rand, _ int) reflect.Value
- func (t T[V]) Get() (V, bool)
- func (t T[V]) IfPresent(fn func(V))
- func (t T[V]) IsEmpty() bool
- func (t T[V]) IsPresent() bool
- func (t T[V]) IsZero() bool
- func (t T[V]) MarshalJSON() ([]byte, error)
- func (t T[V]) Must() V
- func (t T[V]) Or(other T[V]) T[V]
- func (t T[V]) OrElse(defaultValue V) V
- func (t T[V]) OrElseGet(fn func() V) V
- func (t T[V]) OrZero() V
- func (t *T[V]) Scan(src any) error
- func (t T[V]) String() string
- func (t T[V]) ToPtr() *V
- func (t *T[V]) UnmarshalJSON(data []byte) error
- func (t T[V]) Value() (driver.Value, error)
- type Uint
- type Uint16
- type Uint32
- type Uint64
- type Uint8
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type T ¶
type T[V any] struct { // contains filtered or unexported fields }
T represents an option, i.e. a value that may be empty or present.
func FlatMap ¶ added in v0.1.0
FlatMap transforms the value inside the option using the provided function that returns an option. If the option is empty, returns an empty option. Use FlatMap to chain operations that may fail.
parseInt := func(s string) opt.T[int] { ... }
opt.FlatMap(opt.Some("42"), parseInt) // Some(42)
opt.FlatMap(opt.Some("xx"), parseInt) // None
Example ¶
package main
import (
"fmt"
"strconv"
"github.com/lukasngl/opt"
)
func main() {
parseInt := func(s string) opt.T[int] {
n, err := strconv.Atoi(s)
if err != nil {
return opt.None[int]()
}
return opt.Some(n)
}
valid := opt.FlatMap(opt.Some("42"), parseInt)
invalid := opt.FlatMap(opt.Some("abc"), parseInt)
fmt.Println(valid)
fmt.Println(invalid)
}
Output: Some[int](42) None[int]()
func FromPtr ¶ added in v0.1.0
FromPtr creates a new option from a pointer.
If the pointer is nil an empty option is returned, otherwise the value referenced by the pointer will be used as the value for a new present option.
Inverse of T.ToPtr.
Example (Nil) ¶
package main
import (
"fmt"
"time"
"github.com/lukasngl/opt"
)
func main() {
fmt.Printf("%s\n", opt.FromPtr((*time.Time)(nil)))
}
Output: None[time.Time]()
Example (NotZero) ¶
package main
import (
"fmt"
"time"
"github.com/lukasngl/opt"
)
func main() {
// Time that is not zero
value := time.Time{}.Add(time.Hour + time.Minute + time.Second)
fmt.Printf("%s\n", opt.FromPtr(&value))
}
Output: Some[time.Time](0001-01-01 01:01:01 +0000 UTC)
Example (Zero) ¶
package main
import (
"fmt"
"time"
"github.com/lukasngl/opt"
)
func main() {
// Time that is zero, but not the zero value.
value := time.Time{}.In(time.FixedZone("XTC", 42))
fmt.Printf("%s\n", opt.FromPtr(&value))
}
Output: Some[time.Time](0001-01-01 00:00:42 +0000 XTC)
Example (ZeroValue) ¶
package main
import (
"fmt"
"time"
"github.com/lukasngl/opt"
)
func main() {
// Time that is zero and the zero value.
value := time.Time{}
fmt.Printf("%s\n", opt.FromPtr(&value))
}
Output: Some[time.Time](0001-01-01 00:00:00 +0000 UTC)
func FromZeroable ¶
FromZeroable creates a new option from a value.
If the value is zero, an empty option is returned, otherwise a present option containing the option is returned.
Zeroness is determined as follows:
- If the value has an "IsZero() bool" method, it is used to determine zeroness,
- otherwise [reflect.Value#IsZero] is used.
Example (Nil) ¶
package main
import (
"fmt"
"time"
"github.com/lukasngl/opt"
)
func main() {
fmt.Printf("%s\n", opt.FromZeroable((*time.Time)(nil)))
}
Output: None[*time.Time]()
Example (NotZero) ¶
package main
import (
"fmt"
"time"
"github.com/lukasngl/opt"
)
func main() {
// Time that is not zero
value := time.Time{}.Add(time.Hour + time.Minute + time.Second)
fmt.Printf("%s\n", opt.FromZeroable(value))
fmt.Printf("%s\n", opt.FromZeroable(&value))
}
Output: Some[time.Time](0001-01-01 01:01:01 +0000 UTC) Some[*time.Time](0001-01-01 01:01:01 +0000 UTC)
Example (Zero) ¶
package main
import (
"fmt"
"time"
"github.com/lukasngl/opt"
)
func main() {
// Time that is zero, but not the zero value.
value := time.Time{}.In(time.FixedZone("XTC", 42))
fmt.Printf("%s\n", opt.FromZeroable(value))
fmt.Printf("%s\n", opt.FromZeroable(&value))
}
Output: None[time.Time]() None[*time.Time]()
Example (ZeroValue) ¶
package main
import (
"fmt"
"time"
"github.com/lukasngl/opt"
)
func main() {
// Time that is zero and the zero value.
value := time.Time{}
fmt.Printf("%s\n", opt.FromZeroable(value))
fmt.Printf("%s\n", opt.FromZeroable(&value))
}
Output: None[time.Time]() None[*time.Time]()
func Map ¶ added in v0.1.0
Map transforms the value inside the option using the provided function. If the option is empty, returns an empty option.
opt.Map(opt.Some(2), func(n int) int { return n * 2 }) // Some(4)
opt.Map(opt.Some("hi"), strings.ToUpper) // Some("HI")
Example ¶
package main
import (
"fmt"
"github.com/lukasngl/opt"
)
func main() {
o := opt.Some(21)
doubled := opt.Map(o, func(n int) int { return n * 2 })
fmt.Println(doubled)
}
Output: Some[int](42)
func New ¶ added in v0.1.0
New creates a new option from a value and a boolean indicating whether the value is present.
It is the inverse of T.Get.
Example ¶
package main
import (
"fmt"
"github.com/lukasngl/opt"
)
func main() {
// New is the inverse of Get, useful for wrapping comma-ok results
m := map[string]int{"a": 1}
v, ok := m["a"]
o := opt.New(v, ok)
fmt.Println(o)
}
Output: Some[int](1)
func None ¶
None creates a new empty option.
Example ¶
package main
import (
"fmt"
"github.com/lukasngl/opt"
)
func main() {
o := opt.None[string]()
fmt.Println(o)
}
Output: None[string]()
func Some ¶
Some creates a new present option, that contains the given value.
Example ¶
package main
import (
"fmt"
"github.com/lukasngl/opt"
)
func main() {
o := opt.Some(42)
fmt.Println(o)
}
Output: Some[int](42)
func (T[V]) All ¶ added in v0.1.0
All returns an iterator that yields the value if present. This allows using an option in a for-range loop:
for v := range opt.All() {
// v is the unwrapped value
}
func (T[V]) Filter ¶ added in v0.1.0
Filter returns the option if present and the predicate returns true, otherwise returns None.
opt.Some(42).Filter(func(n int) bool { return n > 0 }) // Some(42)
opt.Some(-1).Filter(func(n int) bool { return n > 0 }) // None
Example ¶
package main
import (
"fmt"
"github.com/lukasngl/opt"
)
func main() {
positive := opt.Some(42).Filter(func(n int) bool { return n > 0 })
negative := opt.Some(-1).Filter(func(n int) bool { return n > 0 })
fmt.Println(positive)
fmt.Println(negative)
}
Output: Some[int](42) None[int]()
func (T[V]) Generate ¶
Generate implements quick.Generator.
func (T[V]) Get ¶ added in v0.1.0
Get returns the wrapped value and whether it is present.
Example ¶
package main
import (
"fmt"
"github.com/lukasngl/opt"
)
func main() {
something := opt.Some("hello")
if value, present := something.Get(); present {
fmt.Printf("%s unwrapped to %s", something, value)
}
}
Output: Some[string](hello) unwrapped to hello
func (T[V]) IfPresent ¶ added in v0.1.0
func (t T[V]) IfPresent(fn func(V))
IfPresent calls fn with the wrapped value if present.
Example ¶
package main
import (
"fmt"
"github.com/lukasngl/opt"
)
func main() {
opt.Some("hello").IfPresent(func(s string) {
fmt.Println("got:", s)
})
opt.None[string]().IfPresent(func(s string) {
fmt.Println("got:", s) // not called
})
}
Output: got: hello
func (T[V]) IsEmpty ¶
IsEmpty returns whether the option is empty.
Example ¶
package main
import (
"fmt"
"github.com/lukasngl/opt"
)
func main() {
some := opt.Some(42)
none := opt.None[int]()
fmt.Println(some.IsEmpty(), none.IsEmpty())
}
Output: false true
func (T[V]) IsPresent ¶
IsPresent returns whether the option is present.
Example ¶
package main
import (
"fmt"
"github.com/lukasngl/opt"
)
func main() {
some := opt.Some(42)
none := opt.None[int]()
fmt.Println(some.IsPresent(), none.IsPresent())
}
Output: true false
func (T[V]) IsZero ¶
IsZero returns whether the option is empty. From go1.24 this can be used with omitzero struct tag.
Example ¶
package main
import (
"fmt"
"github.com/lukasngl/opt"
)
func main() {
some := opt.Some(42)
none := opt.None[int]()
fmt.Println(some.IsZero(), none.IsZero())
}
Output: false true
func (T[V]) MarshalJSON ¶
MarshalJSON implements json.Marshaler.
func (T[V]) Must ¶
func (t T[V]) Must() V
Must returns the wrapped value and panics if the github.com/lukasngl/opt.T is empty.
Example ¶
package main
import (
"fmt"
"github.com/lukasngl/opt"
)
func main() {
o := opt.Some(42)
fmt.Println(o.Must())
}
Output: 42
func (T[V]) Or ¶ added in v0.1.0
Or returns the option if present, otherwise returns other.
Example ¶
package main
import (
"fmt"
"github.com/lukasngl/opt"
)
func main() {
primary := opt.None[string]()
fallback := opt.Some("default")
fmt.Println(primary.Or(fallback))
}
Output: Some[string](default)
func (T[V]) OrElse ¶
func (t T[V]) OrElse(defaultValue V) V
OrElse returns the wrapped value if not empty and the given default value otherwise.
Example ¶
package main
import (
"fmt"
"github.com/lukasngl/opt"
)
func main() {
something := opt.Some("hello")
nothing := opt.None[string]()
fmt.Printf("%s %s",
something.OrElse("bye"),
nothing.OrElse("world!"),
)
}
Output: hello world!
func (T[V]) OrElseGet ¶ added in v0.1.0
func (t T[V]) OrElseGet(fn func() V) V
OrElseGet returns the wrapped value if present, otherwise calls fn and returns its result.
Example ¶
package main
import (
"fmt"
"github.com/lukasngl/opt"
)
func main() {
none := opt.None[int]()
result := none.OrElseGet(func() int {
return 100 // expensive computation
})
fmt.Println(result)
}
Output: 100
func (T[V]) OrZero ¶
func (t T[V]) OrZero() V
OrZero returns the wrapped value if not empty and the zero value otherwise.
Example ¶
package main
import (
"fmt"
"github.com/lukasngl/opt"
)
func main() {
nothing := opt.None[string]()
fmt.Printf("%q", nothing.OrZero())
}
Output: ""
func (T[V]) String ¶
String implements fmt.Stringer.
Example ¶
package main
import (
"fmt"
"github.com/lukasngl/opt"
)
func main() {
some := opt.Some("hello")
none := opt.None[string]()
fmt.Println(some.String())
fmt.Println(none.String())
}
Output: Some[string](hello) None[string]()
func (T[V]) ToPtr ¶ added in v0.1.0
func (t T[V]) ToPtr() *V
ToPtr returns a pointer to the wrapped value if present, otherwise a nil pointer.
Inverse of FromPtr.
Example ¶
package main
import (
"fmt"
"github.com/lukasngl/opt"
)
func main() {
some := opt.Some(42)
none := opt.None[int]()
fmt.Println(*some.ToPtr())
fmt.Println(none.ToPtr())
}
Output: 42 <nil>
func (*T[V]) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler.