def_move.go 1.7 KB

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