package koption import ( "reflect" . "gitp78su.ipnodns.ru/svi/kern/kc/helpers" ) // Option -- результат возможно содержащий nil type Option[T any] struct { val *T } // NewSome - полезный результат func NewSome[T any](value T) *Option[T] { // Для некоторых типов нужна дополнительная проверка через reflect v := reflect.ValueOf(value) switch v.Kind() { case reflect.Ptr, reflect.Slice, reflect.Map, reflect.Chan, reflect.Func, reflect.Interface: Hassert(!v.IsNil(), "NewSome[T any](): value==nil") } sf := &Option[T]{val: &value} return sf } // NewNone - нет результата в ответе func NewNone() *Option[any] { return &Option[any]{nil} } // IsSome - проверяет, есть ли значение func (sf *Option[T]) IsSome() bool { return sf.val != nil } // IsSome - проверяет, есть ли значение func (sf *Option[T]) IsNone() bool { return sf.val == nil } // Unwrap - извлекает значение (паника, если None) func (sf *Option[T]) Unwrap() T { Hassert(sf.val != nil, "Option[T].Unwrap(): Called Unwrap on None!") return *sf.val } // UnwrapOr - возвращает значение или дефолтное func (sf Option[T]) UnwrapOr(defaultValue T) T { if sf.val == nil { return defaultValue } return *sf.val } // UnwrapOrFn -- возвращает значение, если оно есть, или результат выполнения функции func (sf *Option[T]) UnwrapOrFn(fn func() T) T { Hassert(fn != nil, "Result[T].UnwrapOrFn(): fn==nil") if sf.val == nil { return fn() } return *sf.val } // Hassert -- проверяет, что нет ошибки (с паникой) func (sf *Option[T]) Hassert(msg string) { Hassert(sf.val != nil, msg+", val==nil\n") } // Assert -- проверяет, что нет ошибки (с паникой только на локальном стенде) func (sf *Option[T]) Assert(msg string) { Assert(sf.val != nil, msg+", val=%v\n") }