如何克隆具有未导出字段的结构? [英] How to clone a structure with unexported field?

查看:87
本文介绍了如何克隆具有未导出字段的结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个类型定义为:

  type T struct {
S string
is [] int
}

那么我该如何去克隆这种类型的对象呢?如果我做了一个简单的任务:

  p:= T {some string,[] int {10,20}} 
q:= p

然后,对 [] int 影响两个对象。由于 T.is 未被导出,因此即使使用反射提取,它也不能被明确复制。



I 'm当前在类型的包中提供了 Clone 方法。但是这对其他软件包中的类似类型没有帮助。有没有另外一种方法可以做到这一点?

解决方案

你不能。这是未报告领域的一点:只有声明包可以修改它们。



请注意,如果 T 类型为在另一个包中声明,你甚至不能写:

  p:= somepackage.T {some string,[] int {10,20}} 

因为这会隐式地尝试设置未导出的 T.is 字段,从而导致编译时错误:

 隐式赋值未导出如果你拥有(或者你可以修改)这个包,那么这个包就是一个包,最好是为 Clone()方法或函数提供一个 SetIs()方法, C $ C> T 。如果第三方软件包没有提供这样的功能,那么您就无能为力。



请注意,使用软件包 不安全 可以做这样的事情,但正如其名称所示:不安全,您应该远离它。



另外请注意,您可以创建 T 其中未被复制,但将成为零值(在 [] int 的情况下将为 nil ) :

  var r somepackage.T 
s:= somepackage.T {S:pS}

fmt.Printf(%q \ n,r)
fmt.Printf(%q\\\
,s)

哪个会输出:

  {[]} 
{some string[]}

但是您不能设置任何非零值未导出的字段 T。是


If I have a type defined as:

type T struct {
    S  string
    is []int
}

then how can I go about cloning an object of this type? If I do a simple assignment:

p := T{"some string", []int{10, 20}}
q := p

Then any changes made to the []int affect both objects. Since T.is is not exported, it cannot be copied over explicitly, even if extracted using reflect.

I'm currently supplying a Clone method in the package of the type itself. But that doesn't help with similar types in other packages. Is there another way to do this?

解决方案

You can't. That's the point of unexported fields: only the declaring package can modify them.

Note that if the T type is declared in another package, you can't even write:

p := somepackage.T{"some string", []int{10, 20}}

because this would implicitly try to set the unexported T.is field and thus results in a compile-time error:

implicit assignment of unexported field 'is' in somepackage.T literal

If you own (or you can modify) the package, best is to provide a Clone() method or function, or provide a SetIs() method for the type T. If a 3rd party package does not provide such functionality, there's nothing you can do about it.

Note that using package unsafe it is possible to do such things, but as its name says: it's unsafe and you should stay away from it.

Also note that you can create new values of T where is is not copied but will be the zero value of its type (which in case of []int will be nil):

var r somepackage.T
s := somepackage.T{S: p.S}

fmt.Printf("%q\n", r)
fmt.Printf("%q\n", s)

Which will output:

{"" []}
{"some string" []}

But you can't set any non-zero value for the unexported field T.is.

这篇关于如何克隆具有未导出字段的结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆