Go 如何创建一个只有接口和值的结构副本

Go 如何创建一个只有接口和值的结构副本,go,struct,interface,Go,Struct,Interface,假设我有一个实现Setter接口的结构: 类型设置器接口{ 设置键字符串,值字符串 } 类型A结构{ m映射[string]字符串 } func a*a设置键字符串、值字符串{ a、 m[键]=值 } 我有一个不同的结构,它包含Setter接口的一些实现 类型持有者结构{ 瓦尔塞特 } h:=保持架{ val:&A{map[string]string{}, } 我需要的是得到一个保存了所有值的h.val结构的副本 我已经尝试了以下解决方案,但没有成功,导致了恐慌:分配到nil映射中的条目 我们在

假设我有一个实现Setter接口的结构:

类型设置器接口{ 设置键字符串,值字符串 } 类型A结构{ m映射[string]字符串 } func a*a设置键字符串、值字符串{ a、 m[键]=值 } 我有一个不同的结构,它包含Setter接口的一些实现

类型持有者结构{ 瓦尔塞特 } h:=保持架{ val:&A{map[string]string{}, } 我需要的是得到一个保存了所有值的h.val结构的副本

我已经尝试了以下解决方案,但没有成功,导致了恐慌:分配到nil映射中的条目

我们在初始化h时定义了映射,因此通过运行h.val.Setk,v,我们不会得到任何错误

l:=反映。新 reflect.ValueOfh.val.Elem.Type, .Interface.Setter l、 刚毛 我如何创建一个结构的副本,而不知道它由哪些字段组成,只知道它实现的接口,并且在变量中包含它的值

p、 将克隆方法添加到Setter接口不是首选的解决方案

将克隆方法添加到Setter接口不是首选解决方案

一般来说,因为只有Setter实现知道如何克隆它,所以没有太多选择

例如:克隆A结构是否应该创建指向同一映射的新结构?还是应该复制映射

如果您的意图是真的要克隆,那么您可能想要第二个,但是您可以看到它很快就会超出简单的反射操作的范围

如果代码实际上只处理结构,则可以传递显式的值。您可能仍然需要.Clone方法或Clonea*a函数

如果唯一的问题是a的零值无效,则可以修复集合:


与内置的New一样,reflect.New只初始化根类型。i、 e.如果你给它A,你会得到初始化的*A,但是m字段将被未初始化,它将被初始化为它的零值,在某些情况下是可以的,但是在映射的情况下它是零,因此恐慌。进行深度复制是一回事,进行深度初始化(尽管类似)是另一回事。在这两种情况下,您都必须使用reflect从根到叶遍历结构,并分别复制/初始化每个结构。祝你好运。不仅是一个结构,而且是实现Setter接口的任何结构。2.如果没有特定的克隆方法无法进行深度复制,是否有一种方法可以通过为所有文件提供其空值(例如自动将Holder.val设置为空映射,而不是nil值)来使用reflect对其进行初始化?有,但这是您需要的吗?您需要克隆还是新函数?克隆函数可能不会创建空对象克隆函数更可取,但如果不可能,新函数就足够了
func (a *A) Set(key string, value string) {
    if a.m == nil {
        a.m = make(map[string]string)
    }
    a.m[key] = value
}