go-deepcopy
                                
                                 go-deepcopy copied to clipboard
                                
                                    go-deepcopy copied to clipboard
                            
                            
                            
                        Fast deep-copy library for Go
Fast deep-copy library for Go
Functionalities
- True deep copy
- Very fast (see benchmarks section)
- Ability to copy almost all Go types (number, string, bool, function, slice, map, struct)
- Ability to copy data between convertible types (for example: copy from inttofloat)
- Ability to copy between pointersandvalues(for example: copy from*inttoint)
- Ability to copy struct fields via struct methods
- Ability to copy inherited fields from embedded structs
- Ability to copy unexported struct fields
- Ability to configure copying behavior
Installation
go get github.com/tiendc/go-deepcopy
Usage
- First example
- Copy between struct fields with different names
- Skip copying struct fields
- Copy struct fields via struct methods
- Copy inherited fields from embedded structs
- Copy unexported struct fields
- Configure copying behavior
First example
    type SS struct {
        B bool
    }
    type S struct {
        I  int
        U  uint
        St string
        V  SS
    }
    type DD struct {
        B bool
    }
    type D struct {
        I int
        U uint
        X string
        V DD
    }
    src := []S{{I: 1, U: 2, St: "3", V: SS{B: true}}, {I: 11, U: 22, St: "33", V: SS{B: false}}}
    var dst []D
    _ = deepcopy.Copy(&dst, &src)
    for _, d := range dst {
        fmt.Printf("%+v\n", d)
    }
    // Output:
    // {I:1 U:2 X: V:{B:true}}
    // {I:11 U:22 X: V:{B:false}}
Copy between struct fields with different names
    type S struct {
        X  int    `copy:"Key"` // 'Key' is used to match the fields
        U  uint
        St string
    }
    type D struct {
        Y int     `copy:"Key"`
        U uint
    }
    src := []S{{X: 1, U: 2, St: "3"}, {X: 11, U: 22, St: "33"}}
    var dst []D
    _ = deepcopy.Copy(&dst, &src)
    for _, d := range dst {
        fmt.Printf("%+v\n", d)
    }
    // Output:
    // {Y:1 U:2}
    // {Y:11 U:22}
Skip copying struct fields
- 
By default, matching fields will be copied. If you don't want to copy a field, use tag value -.
    // S and D both have `I` field, but we don't want to copy it
    // Tag `-` can be used in both struct definitions or just in one
    type S struct {
        I  int
        U  uint
        St string
    }
    type D struct {
        I int `copy:"-"`
        U uint
    }
    src := []S{{I: 1, U: 2, St: "3"}, {I: 11, U: 22, St: "33"}}
    var dst []D
    _ = deepcopy.Copy(&dst, &src)
    for _, d := range dst {
        fmt.Printf("%+v\n", d)
    }
    // Output:
    // {I:0 U:2}
    // {I:0 U:22}
Copy struct fields via struct methods
- 
Note: If a copying method is defined within a struct, it will have higher priority than matching fields. 
type S struct {
    X  int
    U  uint
    St string
}
type D struct {
    x string
    U uint
}
// Copy method should be in form of `Copy<source-field>` (or key) and return `error` type
func (d *D) CopyX(i int) error {
    d.x = fmt.Sprintf("%d", i)
    return nil
}
    src := []S{{X: 1, U: 2, St: "3"}, {X: 11, U: 22, St: "33"}}
    var dst []D
    _ = deepcopy.Copy(&dst, &src)
    for _, d := range dst {
        fmt.Printf("%+v\n", d)
    }
    // Output:
    // {x:1 U:2}
    // {x:11 U:22}
Copy inherited fields from embedded structs
- 
This is default behaviour from version 1.0, for lower versions, you can use custom copying function to achieve the same result. 
    type SBase struct {
        St string
    }
    // Source struct has an embedded one
    type S struct {
        SBase
        I int
    }
    // but destination struct doesn't
    type D struct {
        I  int
        St string
    }
    src := []S{{I: 1, SBase: SBase{"abc"}}, {I: 11, SBase: SBase{"xyz"}}}
    var dst []D
    _ = deepcopy.Copy(&dst, &src)
    for _, d := range dst {
        fmt.Printf("%+v\n", d)
    }
    // Output:
    // {I:1 St:abc}
    // {I:11 St:xyz}
Copy unexported struct fields
- 
By default, unexported struct fields will be ignored when copy. If you want to copy them, use tag attribute required.
    type S struct {
        i  int
        U  uint
        St string
    }
    type D struct {
        i int `copy:",required"`
        U uint
    }
    src := []S{{i: 1, U: 2, St: "3"}, {i: 11, U: 22, St: "33"}}
    var dst []D
    _ = deepcopy.Copy(&dst, &src)
    for _, d := range dst {
        fmt.Printf("%+v\n", d)
    }
    // Output:
    // {i:1 U:2}
    // {i:11 U:22}
Configure copying behavior
- 
Not allow to copy between ptrtype andvalue(default isallow)
    type S struct {
        I  int
        U  uint
    }
    type D struct {
        I *int
        U uint
    }
    src := []S{{I: 1, U: 2}, {I: 11, U: 22}}
    var dst []D
    err := deepcopy.Copy(&dst, &src, deepcopy.CopyBetweenPtrAndValue(false))
    fmt.Println("error:", err)
    // Output:
    // error: ErrTypeNonCopyable: int -> *int
- 
Ignore ErrTypeNonCopyable, the process will not return that kind of error, but some copyings won't be performed. 
    type S struct {
        I []int
        U uint
    }
    type D struct {
        I int
        U uint
    }
    src := []S{{I: []int{1, 2, 3}, U: 2}, {I: []int{1, 2, 3}, U: 22}}
    var dst []D
    // The copy will succeed with ignoring copy of field `I`
    _ = deepcopy.Copy(&dst, &src, deepcopy.IgnoreNonCopyableTypes(true))
    for _, d := range dst {
        fmt.Printf("%+v\n", d)
    }
    // Output:
    // {I:0 U:2}
    // {I:0 U:22}
Benchmarks
Go-DeepCopy vs ManualCopy vs JinzhuCopier vs Deepcopier
This is the benchmark result of the latest version of the lib.
BenchmarkCopy/Go-DeepCopy
BenchmarkCopy/Go-DeepCopy-10         	 1737516	       691.4 ns/op
BenchmarkCopy/ManualCopy
BenchmarkCopy/ManualCopy-10          	25902331	        41.14 ns/op
BenchmarkCopy/jinzhu/copier
BenchmarkCopy/jinzhu/copier-10       	  133630	      8929 ns/op
BenchmarkCopy/ulule/deepcopier
BenchmarkCopy/ulule/deepcopier-10    	   39864	     29785 ns/op
BenchmarkCopy/mohae/deepcopy
BenchmarkCopy/mohae/deepcopy-10      	  491649	      2227 ns/op
BenchmarkCopy/barkimedes/deepcopy
BenchmarkCopy/barkimedes/deepcopy-10 	  483442	      2450 ns/op
BenchmarkCopy/mitchellh/copystructure
BenchmarkCopy/mitchellh/copystructure-10   99501	     11379 ns/op
Contributing
- You are welcome to make pull requests for new functions and bug fixes.
License
- MIT License