github.com/wfusion/gofusion@v1.1.14/common/utils/clone/api.go (about)

     1  //go:build !go1.18
     2  // +build !go1.18
     3  
     4  package clone
     5  
     6  // Clone recursively deep clone v to a new value in heap.
     7  // It assumes that there is no pointer cycle in v,
     8  // e.g. v has a pointer points to v itself.
     9  // If there is a pointer cycle, use Slowly instead.
    10  //
    11  // Clone allocates memory and deeply copies values inside v in depth-first sequence.
    12  // There are a few special rules for following types.
    13  //
    14  //   - Scalar types: all number-like types are copied by value.
    15  //   - func: Copied by value as func is an opaque pointer at runtime.
    16  //   - string: Copied by value as string is immutable by design.
    17  //   - unsafe.Pointer: Copied by value as we don't know what's in it.
    18  //   - chan: A new empty chan is created as we cannot read data inside the old chan.
    19  //
    20  // Unlike many other packages, Clone is able to clone unexported fields of any struct.
    21  // Use this feature wisely.
    22  func Clone(v interface{}) interface{} {
    23  	return cloner.Clone(v)
    24  }
    25  
    26  // Slowly recursively deep clone v to a new value in heap.
    27  // It marks all cloned values internally, thus it can clone v with cycle pointer.
    28  //
    29  // Slowly works exactly the same as Clone. See Clone doc for more details.
    30  func Slowly(v interface{}) interface{} {
    31  	return cloner.CloneSlowly(v)
    32  }
    33  
    34  // Wrap creates a wrapper of v, which must be a pointer.
    35  // If v is not a pointer, Wrap simply returns v and do nothing.
    36  //
    37  // The wrapper is a deep clone of v's value. It holds a shadow copy to v internally.
    38  //
    39  //	t := &T{Foo: 123}
    40  //	v := Wrap(t).(*T)               // v is a clone of t.
    41  //	reflect.DeepEqual(t, v) == true // v equals t.
    42  //	v.Foo = 456                     // v.Foo is changed, but t.Foo doesn't change.
    43  //	orig := Unwrap(v)               // Use `Unwrap` to discard wrapper and return original value, which is t.
    44  //	orig.(*T) == t                  // orig and t is exactly the same.
    45  //	Undo(v)                         // Use `Undo` to discard any change on v.
    46  //	v.Foo == t.Foo                  // Now, the value of v and t are the same again.
    47  func Wrap(v interface{}) interface{} {
    48  	return wrap(t)
    49  }
    50  
    51  // Unwrap returns v's original value if v is a wrapped value.
    52  // Otherwise, simply returns v itself.
    53  func Unwrap(v interface{}) interface{} {
    54  	return unwrap(v)
    55  }
    56  
    57  // Undo discards any change made in wrapped value.
    58  // If v is not a wrapped value, nothing happens.
    59  func Undo(v interface{}) {
    60  	undo(v)
    61  }
    62  
    63  // MarkAsOpaquePointer marks t as an opaque pointer in heap allocator,
    64  // so that all clone methods will copy t by value.
    65  // If t is not a pointer, MarkAsOpaquePointer ignores t.
    66  //
    67  // Here is a list of types marked as opaque pointers by default:
    68  //   - `elliptic.Curve`, which is `*elliptic.CurveParam` or `elliptic.p256Curve`;
    69  //   - `reflect.Type`, which is `*reflect.rtype` defined in `runtime`.
    70  func MarkAsOpaquePointer(t reflect.Type) {
    71  	markAsOpaquePointer(t)
    72  }
    73  
    74  // MarkAsScalar marks t as a scalar type in heap allocator,
    75  // so that all clone methods will copy t by value.
    76  // If t is not struct or pointer to struct, MarkAsScalar ignores t.
    77  //
    78  // In the most cases, it's not necessary to call it explicitly.
    79  // If a struct type contains scalar type fields only, the struct will be marked as scalar automatically.
    80  //
    81  // Here is a list of types marked as scalar by default:
    82  //   - time.Time
    83  //   - reflect.Value
    84  func MarkAsScalar(t reflect.Type) {
    85  	markAsScalar(t)
    86  }
    87  
    88  // SetCustomFunc sets a custom clone function for type t in heap allocator.
    89  // If t is not struct or pointer to struct, SetCustomFunc ignores t.
    90  //
    91  // If fn is nil, remove the custom clone function for type t.
    92  func SetCustomFunc(t reflect.Type, fn Func) {
    93  	setCustomFunc(t, fn)
    94  }
    95  
    96  // FromHeap creates an allocator which allocate memory from heap.
    97  func FromHeap() *Allocator {
    98  	return fromHeap()
    99  }
   100  
   101  // NewAllocator creates an allocator which allocate memory from the pool.
   102  // Both pool and methods are optional.
   103  //
   104  // If methods.New is not nil, the allocator itself is created by calling methods.New.
   105  //
   106  // The pool is a pointer to the memory pool which is opaque to the allocator.
   107  // It's methods' responsibility to allocate memory from the pool properly.
   108  func NewAllocator(pool unsafe.Pointer, methods *AllocatorMethods) (allocator *Allocator) {
   109  	return newAllocator(pool, methods)
   110  }