在 Go 中,您可能会遇到需要创建接口值的副本以维护不同状态的情况。当复制保存指针引用的接口值时,考虑其含义至关重要。本文探讨了如何处理此类场景,并提供了创建真实副本的技术。
在给定的示例中,user1 通过指针引用 Admin 结构体。这意味着当您将 user1 分配给 user2 时,您实际上使 user2 指向相同的底层 Admin 结构。通过 user1 或 user2 进行的任何修改都会影响原始结构。
创建不同副本的一种方法是在 user1 中键入断言值,copy底层 Admin 结构体,并将其地址包装在新的 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
对于更通用的解决方案,您可以利用 Go 的反射功能来检索底层类型,动态创建该类型的新值,并将其包装在新的 User 值中:
if reflect.TypeOf(user1).Kind() == reflect.Ptr { // Pointer: user3 = reflect.New(reflect.ValueOf(user1).Elem().Type()).Interface().(User) } else { // Not pointer: user3 = reflect.New(reflect.TypeOf(user1)).Elem().Interface().(User) }
通过使用反射,可以处理 user1 中的值不是指针的情况。
如果接口值需要复制并保持不同,因此仔细考虑底层类型并使用适当的技术(例如显式复制或反射)来创建真正的副本非常重要。这些方法允许您修改一份副本而不影响原始版本。
以上是在处理指针引用时如何在 Go 中创建接口值的真实副本?的详细内容。更多信息请关注PHP中文网其他相关文章!