Is your feature request related to a problem? Please describe.
Currently working on a codebase where we don't like using pointers for null values, but small types like booleans present problems with using the zero value for when it's absent. False is a perfectly valid value for a partial update of a boolean field in a larger struct.
Describe the solution you'd like
We have a custom built a generic optional value much you'd see in languages like Rust, Java, or Haskell that we'd like to use instead. I propose adding a third option to the optional configuration, something like generic, and then another configuration option much like context_type, optional_generic_type that can be used in place of pointers.
The question is whether to have the generic value without its generic parameter, or include some placeholder like optional.Value[A] or optional.Value[%].
Having this as a third option means you won't break compatibility with <1.18 unless someone opts into it.
Describe alternatives you've considered
The available alternatives of zero values, or pointers each have significant drawbacks.
Additional context
This is the full implementation of our generic optional type optional.Value, but the configuration options allow anyone else to sub their own in. Happen to open a Pull Request with the changes if you like the idea.
package optional
import (
"encoding/json"
)
type Value[V any] struct {
value V
ok bool
}
func Some[V any](value V) Value[V] {
return Value[V]{value: value, ok: true}
}
func None[V any]() Value[V] {
return Value[V]{ok: false}
}
func (v Value[V]) Unpack() (V, bool) {
return v.value, v.ok
}
func (v Value[V]) Get(fallback V) V {
if v.ok {
return v.value
}
return fallback
}
func FromPtr[V any](ptr *V) Value[V] {
if ptr == nil {
return None[V]()
}
return Some(*ptr)
}
func (value Value[V]) MarshalJSON() ([]byte, error) {
if value.ok {
return json.Marshal(value.value)
} else {
return json.Marshal((*V)(nil))
}
}
func (value *Value[V]) UnmarshalJSON(data []byte) error {
v := (*V)(nil)
err := json.Unmarshal(data, &v)
if err != nil {
return err
}
if v != nil {
value.value = *v
value.ok = true
}
return nil
}
Is your feature request related to a problem? Please describe. Currently working on a codebase where we don't like using pointers for null values, but small types like booleans present problems with using the
zero
value for when it's absent. False is a perfectly valid value for a partial update of a boolean field in a larger struct.Describe the solution you'd like We have a custom built a generic
optional
value much you'd see in languages like Rust, Java, or Haskell that we'd like to use instead. I propose adding a third option to theoptional
configuration, something likegeneric
, and then another configuration option much likecontext_type
,optional_generic_type
that can be used in place of pointers.The question is whether to have the generic value without its generic parameter, or include some placeholder like
optional.Value[A]
oroptional.Value[%]
.Having this as a third option means you won't break compatibility with <1.18 unless someone opts into it.
Describe alternatives you've considered The available alternatives of zero values, or pointers each have significant drawbacks.
Additional context This is the full implementation of our generic optional type
optional.Value
, but the configuration options allow anyone else to sub their own in. Happen to open a Pull Request with the changes if you like the idea.