def_box.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. // package def_move -- параметрический контейнер с семантикой перемещения.
  2. package def_move
  3. import (
  4. "reflect"
  5. "gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_spec"
  6. "gitp78su.ipnodns.ru/svi/kern/v4/lev0/helpers"
  7. )
  8. // Move -- параметрический контейнер с семантикой перемещения
  9. type Move[T any] struct {
  10. type_ def_spec.ATxt
  11. val *T // Фактическое значение
  12. }
  13. const (
  14. str5 = def_spec.ATxt("NewBox(): val==nil")
  15. )
  16. // NewMove -- возвращает новый параметрический контейнер с семантикой перемещения
  17. func NewMove[T any](val T) *Move[T] {
  18. v := reflect.ValueOf(val)
  19. switch v.Kind() {
  20. case reflect.Pointer, reflect.Slice, reflect.Map, reflect.Chan, reflect.Func, reflect.Interface:
  21. isNil := def_spec.Bool(v.IsNil())
  22. helpers.If(isNil).Hassert(str5)
  23. }
  24. sf := &Move[T]{
  25. val: &val,
  26. type_: def_spec.Sprintf("%T", val),
  27. }
  28. _ = def_spec.IFixBox[T](sf)
  29. _ = def_spec.IMutBox[T](sf)
  30. return sf
  31. }
  32. // Set -- устанавливает внутреннее значение
  33. func (sf *Move[T]) Set(val T) {
  34. v := reflect.ValueOf(val)
  35. switch v.Kind() {
  36. case reflect.Pointer, reflect.Slice, reflect.Map, reflect.Chan, reflect.Func, reflect.Interface:
  37. isNil := def_spec.Bool(v.IsNil())
  38. helpers.If(isNil).Hassert(str5)
  39. }
  40. sf.val = &val
  41. }
  42. // Move -- перемещает другому владельцу хранимое значение
  43. func (sf *Move[T]) Move() T {
  44. defer func() {
  45. sf.val = nil
  46. }()
  47. helpers.If(sf.val == nil).Hassert("Box.Move[%v]: val already moved", sf.type_)
  48. return *sf.val
  49. }