A lightweight Go library for copying struct values with shallow and deep copy support. Handle pointers, nested structs, slices, maps, and common data types safely and efficiently.
- 🛠 Shallow & Deep Copy
Choose between
ShallowCopyStruct
(shared references) orDeepCopyStruct
(fully independent copies) - 🧩 Type-Safe Automatically skips non-assignable fields and invalid types
- 🔍 Nested Structure Support Recursively copies structs, pointers, slices, and maps
- ⚡ Efficient Optimized field matching with precomputed maps
- 🛡️ Error Handling Clear error messages for invalid inputs
go get github.com/knbr13/copier
package main
import (
"fmt"
"github.com/knbr13/copier"
)
type User struct {
Name string
Age int
}
func main() {
src := User{Name: "Alice", Age: 30}
var dst User
// Shallow copy
if err := copier.ShallowCopyStruct(&dst, &src); err != nil {
panic(err)
}
// Deep copy (same syntax)
// copier.DeepCopyStruct(&dst, &src)
fmt.Printf("Copied: %+v", dst) // Output: {Name:Alice Age:30}
}
// Shallow copy - shares pointers/slices/maps
func ShallowCopyStruct(dst, src interface{}) error
// Deep copy - creates independent copies
func DeepCopyStruct(dst, src interface{}) error
- Destination must be a pointer to a struct
- Source can be a struct or pointer to struct
- Field matching is case-sensitive and requires exact name matches
- Unexported fields are not copied
- Interface fields are shallow copied
num := 42
src := &struct{ Ptr *int }{Ptr: &num}
var dst struct{ Ptr *int }
copier.ShallowCopyStruct(&dst, src) // dst.Ptr == src.Ptr (shared)
copier.DeepCopyStruct(&dst, src) // dst.Ptr != src.Ptr (new copy)
type Address struct { City string }
type User struct {
Name string
Address *Address
}
src := &User{Name: "Bob", Address: &Address{City: "Paris"}}
var dst User
copier.DeepCopyStruct(&dst, src)
src.Address.City = "London" // dst.Address.City remains "Paris"
src := &struct {
IDs []int
Data map[string]bool
}{
IDs: []int{1, 2, 3},
Data: map[string]bool{"admin": true},
}
var dst struct {
IDs []int
Data map[string]bool
}
copier.DeepCopyStruct(&dst, src)
src.IDs[0] = 99 // dst.IDs remains [1,2,3]
src.Data["admin"] = false // dst.Data["admin"] remains true
Common errors include:
// Nil inputs
copier.ShallowCopyStruct(nil, &src) // Error: "destination cannot be nil"
// Type mismatches
src := struct{ A int }{A: 1}
dst := struct{ A string }{}
copier.DeepCopyStruct(&dst, &src) // Skipped: type mismatch
// Invalid destination
copier.DeepCopyStruct("not-a-pointer", &src) // Error: "pointer to a struct"
Contributions welcome!
- Fork the repository
- Create a feature branch
- Submit a PR with tests
Report bugs via GitHub Issues.
MIT License - See LICENSE for details.