How to Deep Copy an Interface Value in Go
When working with interfaces in Go, it's essential to realize that interfaces hold a reference to their underlying value. Modifying the copy of an interface value can inadvertently affect the original value as well. This issue commonly arises when creating interface values using pointers to underlying types.
Understanding the Issue
Consider the following User interface:
type User interface { Name() string SetName(name string) }
And an implementation with an Admin struct:
type Admin struct { name string } func (a *Admin) Name() string { return a.name } func (a *Admin) SetName(name string) { a.name = name }
In the example provided, a pointer to an Admin struct is assigned to the user1 variable of type User. However, when user2 is created by assigning it the value of user1, both variables reference the same underlying Admin struct. As a result, changing the name through user2 also changes the name through user1.
Creating Distinct Copies
To create distinct copies of interface values, there are several options:
1. Using Type Assertion and Struct Copying
This method involves type asserting the value in user1, making a copy of the underlying struct, and wrapping the copy's address in a new User value:
var user2 User padmin := user1.(*Admin) // Obtain *Admin pointer admin2 := *padmin // Make a copy of the Admin struct user2 = &admin2 // Wrap its address in another User user2.SetName("user2")
2. Using Reflection
Reflection can be utilized to create a new value of the same dynamic type as the interface value, ensuring a deep copy. Here's how:
var user3 User if reflect.TypeOf(user1).Kind() == reflect.Ptr { user3 = reflect.New(reflect.ValueOf(user1).Elem().Type()).Interface().(User) } else { user3 = reflect.New(reflect.TypeOf(user1)).Elem().Interface().(User) } user3.SetName("user3")
By deeply copying the interface value, we create a distinct copy that can be modified without affecting the original.
The above is the detailed content of How to Deep Copy Interface Values in Go?. For more information, please follow other related articles on the PHP Chinese website!