github.com/go-board/x-go@v0.1.2-0.20220610024734-db1323f6cb15/option/option.go (about) 1 package option 2 3 // Type Option represents an optional value: 4 // every Option is either Some and contains a value, 5 // or None, and does not. 6 // - Initial values 7 // - Return values for functions that are not defined over their entire input range (partial functions) 8 // - Return value for otherwise reporting simple errors, where None is returned on error 9 // - Optional struct fields 10 // - Struct fields that can be loaned or "taken" 11 // - Optional function arguments 12 // - Nullable pointers 13 // - Swapping things out of difficult situations 14 // 15 // Options are commonly paired with pattern matching to query the presence of a value and take action, always accounting for the None case. 16 type Option struct { 17 data interface{} 18 v bool 19 } 20 21 // Some value T 22 func Some(s interface{}) Option { return Option{data: s, v: true} } 23 24 // No value 25 func None() Option { return Option{} } 26 27 func (o Option) IsSome() bool { return o.v } 28 29 func (o Option) IsNone() bool { return !o.IsSome() } 30 31 // Returns None if the option is None, otherwise returns optb. 32 func (o Option) And(optb Option) Option { 33 if o.IsNone() { 34 return None() 35 } 36 return optb 37 } 38 39 func (o Option) AndThen(fn func(interface{}) Option) Option { 40 if o.IsNone() { 41 return None() 42 } 43 return fn(o.data) 44 } 45 46 // Returns the option if it contains a value, otherwise returns optb. 47 func (o Option) Or(optb Option) Option { 48 if o.IsNone() { 49 return optb 50 } 51 return o 52 } 53 54 func (o Option) OrElse(fn func() Option) Option { 55 if o.IsNone() { 56 return fn() 57 } 58 return o 59 } 60 61 func (o Option) Map(fn func(interface{}) interface{}) Option { 62 if o.IsNone() { 63 return None() 64 } 65 return Some(fn(o.data)) 66 } 67 68 // Applies a function to the contained value (if any), or returns the provided default (if not). 69 func (o Option) MapOr(defValue interface{}, fn func(interface{}) interface{}) Option { 70 if o.IsSome() { 71 return Some(fn(o.data)) 72 } 73 return Some(defValue) 74 } 75 76 // Returns the contained Some value, consuming the self value. 77 // 78 // Because this function may panic, its use is generally discouraged. 79 // Instead, prefer to use pattern matching and handle the None case explicitly, 80 // or call `unwrap_or`, `unwrap_or_else`. 81 func (o Option) Unwrap() interface{} { 82 if o.IsNone() { 83 panic("unwrap Option None") 84 } 85 return o.data 86 } 87 88 func (o Option) UnwrapOr(v interface{}) interface{} { 89 if o.IsNone() { 90 return v 91 } 92 return o.data 93 } 94 95 func (o Option) UnwrapOrElse(fn func() interface{}) interface{} { 96 if o.IsNone() { 97 return fn() 98 } 99 return o.data 100 }