ホームページ >バックエンド開発 >Golang >Go でインターフェイス値を適切にコピーするには?

Go でインターフェイス値を適切にコピーするには?

Patricia Arquette
Patricia Arquetteオリジナル
2024-12-11 01:35:13192ブラウズ

How to Properly Copy Interface Values in Go?

Go でのインターフェイス値のコピー

Go でインターフェイスを操作する場合、コピーを作成する必要があるシナリオに遭遇する可能性があります。インターフェース値。インターフェイス値をコピーする動作は、インターフェイスの基になる型によって異なります。

ポインター インターフェイスのコピー

この例では、ユーザー インターフェイスにはポインター型があります。あるユーザー変数を別のユーザー変数に割り当てると、基になるポインター値がコピーされます。これは、元のデータとコピーの両方が同じ基になるデータを指していることを意味します。いずれかの変数を通じて行われた変更は両方に反映されます。

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"
}

この例では、user2 の変更は user1 にも影響します。これは、user1 と user2 の両方が同じ Admin インスタンスを指しているためです。

解決策: 基礎となる値の複製

インターフェイス値の真のコピーを作成するには、以下が必要です。基礎となるデータのクローンを作成します。これを実現する 1 つの方法は、リフレクションを使用することです。以下に例を示します。

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"

このコードは、基礎となる型の新しいインスタンスを作成し、データのクローンを作成し、それを新しいユーザー インターフェイスでラップします。これで、user3 を変更しても user1 には影響しなくなりました。

以上がGo でインターフェイス値を適切にコピーするには?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。