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 サイトの他の関連記事を参照してください。