How to Build a Deep Copy Utility in Go Using reflect

This article walks through implementing a deep‑copy function in Go with the reflect package, explaining key concepts such as reflect.ValueOf, reflect.New, pointer handling, and recursive copying, and provides a complete code example and visual diagrams.

Nullbody Notes
Nullbody Notes
Nullbody Notes
How to Build a Deep Copy Utility in Go Using reflect

Many developers who work on CRUD applications rarely use Go's reflect package, but understanding it is essential for tasks like deep copying. This project demonstrates a 100‑line implementation that helps readers deepen their grasp of reflect basics.

The function reflect.ValueOf() converts an interface{} value into a reflect.Value structure. Internally, a reflect.Value holds the same underlying interface{}, allowing access to the dynamic type and dynamic value of the original object.

Using reflect.New(original.Type()).Elem() creates a new pointer of the same type as the source and then dereferences it to obtain a fresh value. This mirrors the C idiom int *p = new(int), allocating a new object of the required type.

func copyRecursive(src, dest reflect.Value) {
    switch src.Kind() {
    case reflect.Ptr: // src is a pointer; copying the pointer directly would not be a deep copy
        original := src.Elem()
        if src.IsNil() || !original.IsValid() {
            return
        }
        // Allocate a new object of the same type
        destValue := reflect.New(original.Type())
        // Recursively copy the original's value into the new object's element
        copyRecursive(original, destValue.Elem())
        // Make dest point to the newly allocated object
        dest.Set(destValue)
    }
    // ... omitted other kinds ...
}

The author explains why a simple dest.Set(src) is insufficient: assigning a pointer copies the address, so both variables refer to the same object, which is not a deep copy. Instead, a new object must be created, and its type is obtained via original.Type().

After allocating the new object, its fields contain zero values. Therefore the recursive call to copyRecursive copies the actual data from original into destValue.Elem(), completing the deep‑copy process.

Two diagrams illustrate the relationship between interface{}, reflect.Value, and the newly allocated pointer, helping readers visualize the transformation steps.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

ProgrammingGoruntimedeep copyreflect
Nullbody Notes
Written by

Nullbody Notes

Go backend development, learning open-source project source code together, focusing on simplicity and practicality.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.