Documentation
¶
Overview ¶
Package clone provides functions to deep clone any Go data. It also provides a wrapper to protect a pointer from any unexpected mutation.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Clone ¶
func Clone(v interface{}) interface{}
Clone recursively deep clone v to a new value. It assumes that there is no recursive pointers in v, e.g. v has a pointer points to v itself.
func Slowly ¶
func Slowly(v interface{}) interface{}
Slowly recursively deep clone v to a new value. It marks all cloned values internally, thus it can clone recursive pointers in v.
Example ¶
type ListNode struct { Data int Next *ListNode } node1 := &ListNode{ Data: 1, } node2 := &ListNode{ Data: 2, } node3 := &ListNode{ Data: 3, } node1.Next = node2 node2.Next = node3 node3.Next = node1 // We must use `Slowly` to clone a circular linked list. node := Slowly(node1).(*ListNode) for i := 0; i < 10; i++ { fmt.Println(node.Data) node = node.Next }
Output: 1 2 3 1 2 3 1 2 3 1
func Undo ¶
func Undo(v interface{})
Undo discards any change made in wrapped value. If v is not a wrapped value, nothing happens.
func Unwrap ¶
func Unwrap(v interface{}) interface{}
Unwrap returns v's original value if v is a wrapped value. Otherwise, simply returns v itself.
func Wrap ¶
func Wrap(v interface{}) interface{}
Wrap creates a wrapper of v, which must be a pointer. If v is not a pointer, Wrap simply returns v and do nothing.
The wrapper is a deep clone of v's value. It holds a shadow copy to v internally.
t := &T{Foo: 123} v := Wrap(t).(*T) // v is a clone of t. reflect.DeepEqual(t, v) == true // v equals t. v.Foo = 456 // v.Foo is changed, but t.Foo doesn't change. orig := Unwrap(v) // Use `Unwrap` to discard wrapper and return original value, which is t. orig.(*T) == t // orig and t is exactly the same. Undo(v) // Use `Undo` to discard any change on v. v.Foo == t.Foo // Now, the value of v and t are the same again.
Example ¶
// Suppose we have a type T defined as following. // type T struct { // Foo int // } v := &T{ Foo: 123, } w := Wrap(v).(*T) // Wrap value to protect it. // Use w freely. The type of w is the same as that of v. // It's OK to modify w. The change will not affect v. w.Foo = 456 fmt.Println(w.Foo) // 456 fmt.Println(v.Foo) // 123 // Once we need the original value stored in w, call `Unwrap`. orig := Unwrap(w).(*T) fmt.Println(orig == v) // true fmt.Println(orig.Foo) // 123 // Or, we can simply undo any change made in w. // Note that `Undo` is significantly slower than `Unwrap`, thus // the latter is always preferred. Undo(w) fmt.Println(w.Foo) // 123
Output: 456 123 true 123 123
Types ¶
This section is empty.