Mastering Deep Copy in Go: A Complete Reflection-Based Implementation
This article explains how to implement a generic deep‑copy function in Go using reflection, detailing the Interface definition, the Copy and Iface wrappers, the recursive copyRecursive logic, and key techniques such as interface design and recursive traversal to produce fully independent copies of complex data structures.
Overview
In Go, copying values can be shallow or deep. Deep copy creates an independent replica of a value and all referenced data, which is essential when a completely separate copy is required.
Code Structure
The implementation consists of four main parts:
Interface – defines the DeepCopy method.
Iface – a compatibility alias that forwards to Copy.
Copy – the core function that creates a deep copy.
copyRecursive – recursive logic that walks through the source value.
Key Functions
DeepCopy Interface
type Interface interface {
DeepCopy() interface{}
}Any type implementing this interface must provide a DeepCopy method that returns a deep‑copied instance.
Iface Function
func Iface(iface interface{}) interface{} {
return Copy(iface)
}This wrapper preserves backward compatibility by delegating to Copy.
Copy Function
func Copy(src interface{}) interface{} {
if src == nil {
return nil
}
original := reflect.ValueOf(src)
cpy := reflect.New(original.Type()).Elem()
copyRecursive(original, cpy)
return cpy.Interface()
}The function checks for nil, obtains a reflective value, creates an empty value of the same type, calls copyRecursive, and returns the resulting interface.
copyRecursive Function
func copyRecursive(original, cpy reflect.Value) {
if original.CanInterface() {
if copier, ok := original.Interface().(Interface); ok {
cpy.Set(reflect.ValueOf(copier.DeepCopy()))
return
}
}
switch original.Kind() {
case reflect.Ptr:
// handle pointers
case reflect.Interface:
// handle interfaces
case reflect.Struct:
// special handling for time.Time, then field‑by‑field copy
case reflect.Slice:
// create new slice and copy each element
case reflect.Map:
// create new map and copy each key/value pair
default:
cpy.Set(original)
}
}The recursive routine first checks whether the value implements the Interface and uses its DeepCopy method if available. Otherwise it switches on the kind of the value and handles pointers, interfaces, structs (including a special case for time.Time), slices, maps, and a default fall‑back that copies the value directly.
Key Techniques
Reflection – uses the reflect package to handle arbitrary types dynamically.
Interface Design – the Interface allows custom types to provide their own deep‑copy logic, improving extensibility.
Recursive Copy – recursion ensures nested structures are fully duplicated.
Conclusion
The presented Go deep‑copy implementation leverages reflection and a custom interface to deliver a generic, efficient solution suitable for scenarios where a completely independent copy of complex data structures is required.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Ops Development & AI Practice
DevSecOps engineer sharing experiences and insights on AI, Web3, and Claude code development. Aims to help solve technical challenges, improve development efficiency, and grow through community interaction. Feel free to comment and discuss.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
