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

How to Properly Copy Interface Values in Go?

Patricia Arquette
Patricia ArquetteOriginal
2024-12-11 01:35:13202browse

How to Properly Copy Interface Values in Go?

Copying Interface Values in Go

When working with interfaces in Go, it is possible to encounter scenarios where you need to make a copy of an interface value. The behavior of copying interface values differs depending on the underlying type of the interface.

Copying Pointer Interfaces

In your example, the User interface has a pointer type. When you assign one User variable to another, the underlying pointer value is copied. This means that both the original and the copy point to the same underlying data. Any modifications made through either variable will be reflected in both.

type User interface {
    Name() string
    SetName(name string)
}

type Admin struct {
    name string
}

func (a *Admin) Name() string {
    return a.name
}

func (a *Admin) SetName(name string) {
    a.name = name
}

func main() {
    var user1 User
    user1 = &Admin{name: "user1"}

    var user2 User
    user2 = user1

    user2.SetName("user2")

    fmt.Println("User1's name:", user1.Name())  // "user2"
    fmt.Println("User2's name:", user2.Name())  // "user2"
}

In this example, the modification of user2 affects user1 as well. This is because both user1 and user2 point to the same Admin instance.

Solution: Cloning the Underlying Value

To create a true copy of an interface value, you need to clone the underlying data. One way to achieve this is to use reflection. Here's an example:

var user3 User

typ := reflect.TypeOf(user1)
val := reflect.ValueOf(user1)

if typ.Kind() == reflect.Ptr {
    newPtr := reflect.New(typ.Elem())
    newPtr.Elem().Set(val.Elem())
    user3 = newPtr.Interface().(User)
} else {
    newVal := reflect.New(typ)
    newVal.Elem().Set(val)
    user3 = newVal.Elem().Interface().(User)
}

user3.SetName("user3")

fmt.Println("User1's name:", user1.Name())  // "user1"
fmt.Println("User3's name:", user3.Name())  // "user3"

This code creates a new instance of the underlying type, clones the data, and wraps it in a new User interface. Now, any modifications to user3 will not affect user1.

The above is the detailed content of How to Properly 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