Documentation
¶
Overview ¶
Package deepclone copies Go values whose state can be represented as memory-owned data.
Clone returns a deep copy or an error when a value cannot be honestly cloned. MustClone is the convenience form for values that are known to be supported.
Reflection cloning preserves supported object graphs, including circular references. Nil pointers, slices, maps, interfaces, channels, functions, and unsafe pointers keep their nil meaning. Non-nil channels, functions, and unsafe pointers are rejected because they represent runtime identity or execution capability rather than ordinary memory-owned data. Slice capacity is an allocation detail, not a public cloning guarantee. Pointer-to-field and pointer-to-array-element relationships are preserved only when the addressable owner is cloned in the same graph.
The package does not use unsafe to read or write unexported fields. Reflection cloning preserves value-like unexported fields by shallow-copying the struct first, but rejects unexported reference-like state that it cannot safely deep-clone. Types with private invariants or resource ownership should implement Cloner[T] and define their own behavior.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Clone ¶
Clone returns a deep copy of src.
Clone preserves circular references when it uses reflection. Types that implement Cloner[T] control their own cloning behavior.
Example ¶
package main
import (
"fmt"
"github.com/kaptinlin/deepclone"
)
func main() {
original := map[string][]int{
"scores": {90, 85, 77},
}
cloned, err := deepclone.Clone(original)
if err != nil {
panic(err)
}
// Modify the clone — original is unaffected
cloned["scores"][0] = 100
fmt.Println("original:", original["scores"])
fmt.Println("cloned: ", cloned["scores"])
}
Output: original: [90 85 77] cloned: [100 85 77]
Example (Nil) ¶
package main
import (
"fmt"
"github.com/kaptinlin/deepclone"
)
func main() {
var original []int
cloned := deepclone.MustClone(original)
fmt.Println("nil preserved:", cloned == nil)
}
Output: nil preserved: true
Example (Slice) ¶
package main
import (
"fmt"
"github.com/kaptinlin/deepclone"
)
func main() {
original := []string{"a", "b", "c"}
cloned := deepclone.MustClone(original)
cloned[0] = "z"
fmt.Println("original:", original)
fmt.Println("cloned: ", cloned)
}
Output: original: [a b c] cloned: [z b c]
Example (Struct) ¶
package main
import (
"fmt"
"github.com/kaptinlin/deepclone"
)
func main() {
type Address struct {
City string
State string
}
type Person struct {
Name string
Age int
Address *Address
}
original := Person{
Name: "Alice",
Age: 30,
Address: &Address{
City: "Portland",
State: "OR",
},
}
cloned := deepclone.MustClone(original)
// Modify the clone's nested pointer — original is unaffected
cloned.Address.City = "Seattle"
cloned.Address.State = "WA"
fmt.Println("original:", original.Address.City, original.Address.State)
fmt.Println("cloned: ", cloned.Address.City, cloned.Address.State)
}
Output: original: Portland OR cloned: Seattle WA
Types ¶
type Cloner ¶ added in v0.2.17
type Cloner[T any] interface { // Clone returns a copy that can be used independently of the original. Clone() (T, error) }
Cloner lets a type define its own deep-cloning behavior.
Clone must return a copy that can be used independently of the original. Circular reference detection does not apply inside custom Clone methods.
Example ¶
package main
import (
"fmt"
"github.com/kaptinlin/deepclone"
)
// Document is a type that implements the Cloner interface
// to provide custom deep cloning behavior.
type Document struct {
Title string
Tags []string
}
func (d Document) Clone() (Document, error) {
tags, err := deepclone.Clone(d.Tags)
if err != nil {
return Document{}, err
}
return Document{
Title: d.Title,
Tags: tags,
}, nil
}
func main() {
original := Document{
Title: "Guide",
Tags: []string{"go", "clone"},
}
cloned := deepclone.MustClone(original)
cloned.Tags[0] = "rust"
fmt.Println("original:", original.Tags)
fmt.Println("cloned: ", cloned.Tags)
}
Output: original: [go clone] cloned: [rust clone]
type UnsupportedError ¶ added in v0.2.17
UnsupportedError reports a value that cannot be honestly deep-cloned.
func (*UnsupportedError) Error ¶ added in v0.2.17
func (e *UnsupportedError) Error() string
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
basic
command
Package main demonstrates basic usage of the deepclone library.
|
Package main demonstrates basic usage of the deepclone library. |
|
circular
command
Package main demonstrates handling circular references with the deepclone library.
|
Package main demonstrates handling circular references with the deepclone library. |
|
custom
command
Package main demonstrates custom cloning behavior with the deepclone library.
|
Package main demonstrates custom cloning behavior with the deepclone library. |