在 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 實例。
解決方案:複製基礎值
要建立介面值的真實副本,您需要複製底層資料。實現此目的的一種方法是使用反射。以下是一個範例:
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中文網其他相關文章!