Home >Backend Development >Golang >How to Achieve a Deep Copy of Interface Values in Go?

How to Achieve a Deep Copy of Interface Values in Go?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-12-07 20:57:12739browse

How to Achieve a Deep Copy of Interface Values in Go?

Deep Copy of Interface Values in Go

Copying an interface value directly in Go results in a shallow copy, meaning changes made to the copied value affect the original as well. This is because interfaces hold a reference to the underlying concrete type.

Cause of Name Change

To understand the issue in the provided code, let's analyze how interface values work. The User interface represents a contract, and both Admin and User implement this contract. When assigning user1 to user2, we're essentially creating a reference to the same Admin instance. Modifying user2's Name() method directly modifies the shared Admin instance, which consequently changes user1's name as well.

Solution with Reflection

To achieve a deep copy, we need to create a new instance of the underlying concrete type and wrap it in a new User interface value. One way to do this is to use reflection. We can use the reflect.ValueOf() and reflect.Elem() functions to get the underlying value stored in user1. Then, we can use reflect.New() to create a new instance of the same type and reflect.MethodByName() to obtain the Name() method. Finally, we can call the SetName() method on the new instance and wrap it in a new User interface value.

func CloneUser(user User) User {
    val := reflect.ValueOf(user)
    if val.Kind() != reflect.Ptr {
        panic("expected pointer")
    }
    elem := val.Elem()
    t := elem.Type()
    newElem := reflect.New(t).Elem()
    newElem.MethodByName("SetName").Call([]reflect.Value{reflect.ValueOf(newElem.String())})
    return newElem.Interface().(User)
}

Using this function, we can create a copy that doesn't affect the original:

var user2 User = CloneUser(user1)
user2.SetName("user2")
fmt.Println(user1.Name(), user2.Name()) // Outputs: user1 user2

The above is the detailed content of How to Achieve a Deep Copy of Interface Values in Go?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn