Go でインターフェイス値をディープ コピーする方法
Go でインターフェイスを操作する場合、インターフェイスがへの参照を保持していることを認識することが重要です。その根底にある価値観。インターフェイス値のコピーを変更すると、元の値にも誤って影響を与える可能性があります。この問題は、基になる型へのポインタを使用してインターフェイス値を作成するときによく発生します。
問題の理解
次のユーザー インターフェイスを考慮してください:
type User interface { Name() string SetName(name string) }
Admin 構造体を使用した実装:
type Admin struct { name string } func (a *Admin) Name() string { return a.name } func (a *Admin) SetName(name string) { a.name = name }
提供された例では、 Admin 構造体へのポインタは、User 型の user1 変数に割り当てられます。ただし、user1 の値を割り当てて user2 を作成すると、両方の変数が同じ基礎となる Admin 構造体を参照します。その結果、user2 を通じて名前を変更すると、user1 を通じて名前も変更されます。
個別のコピーの作成
インターフェイス値の個別のコピーを作成するには、いくつかのオプションがあります。
1.型アサーションと構造体のコピーの使用
このメソッドには、user1 の値の型アサート、基になる構造体のコピーの作成、およびコピーのアドレスを新しい User 値でラップすることが含まれます:
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.リフレクションの使用
リフレクションを利用して、インターフェイス値と同じ動的タイプの新しい値を作成し、ディープ コピーを確保できます。その方法は次のとおりです。
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")
インターフェイス値を深くコピーすることで、元の値に影響を与えることなく変更できる個別のコピーを作成します。
以上がGo でインターフェイス値をディープコピーするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。