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

How to Deep Copy Interface Values in Go?

Barbara Streisand
Barbara StreisandOriginal
2024-12-26 14:56:11463browse

How to Deep Copy Interface Values in Go?

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!

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