<p>I want to clone a struct. I have no foreknowledge of it's type, but I want a new empty copy of it. How can I create one? Demo: <a href="https://play.golang.org/p/7XcrhoTHejn" rel="nofollow">https://play.golang.org/p/7XcrhoTHejn</a></p>
<hr/>**评论:**<br/><br/>TheMerovius: <pre><p>Using <a href="https://play.golang.org/p/vQ3O38QnE9j" rel="nofollow">reflect.New</a></p>
<p>[edit] alternatively using <a href="https://play.golang.org/p/pDO0k3kCJ_a" rel="nofollow">reflect.Zero</a>, which might be less allocation (haven't tested). Didn't expect that to work…</p></pre>Xeoncross: <pre><p>In both examples, <code>b</code> is now an <code>interface{}</code> according to the compiler so any kind of type checks seem to fail. I tried changing the code to <code>reflect.Zero(reflect.TypeOf(a)).Interface().(Foo)</code> but then I just have a <code>(*main.Foo)(nil)</code> that I'm not sure what to do with.</p></pre>TheMerovius: <pre><p>I don't understand this. Above you said, that you do not have any knowledge of the type. That seems to preclude type-information for the compiler anyway. It would be really helpful, if you could give more information of the problem you are trying to solve, because if you can do <code>b := (someExpresion).(Foo)</code>, you can also just do <code>b := Foo{}</code> and be done with it.</p>
<p>And both the examples that I posted provide you with an empty <code>main.Foo</code>, not <code>(*main.Foo)(nil)</code>, so I see even less where your problem is, that seems to be exactly what you wanted? You can also add type-assertions if you prefer (though really, still don't get the point of that): <a href="https://play.golang.org/p/QxUwwfr29xz" rel="nofollow">https://play.golang.org/p/QxUwwfr29xz</a> <a href="https://play.golang.org/p/RB5PzuenPY2" rel="nofollow">https://play.golang.org/p/RB5PzuenPY2</a></p>
<p>I'm afraid I don't understand why you don't consider this a full answer of your question?</p></pre>Xeoncross: <pre><p>I'm trying to get something ready to post online and that might help answer any questions. However, in the mean time your answer was helpful, so thank you. </p>
<p>The reason I am getting back a <code>*main.Foo</code> or <code>(*main.Foo)(nil)</code> is because I'm feeding <code>a</code> as an <code>*Foo</code>.</p>
<p>Consider this: <a href="https://play.golang.org/p/Ok_q3lx490h" rel="nofollow">https://play.golang.org/p/Ok_q3lx490h</a></p></pre>TheMerovius: <pre><blockquote>
<p>I tried changing the code to <code>reflect.Zero(reflect.TypeOf(a)).Interface().(Foo)</code> but then I just have a <code>(*main.Foo)(nil)</code></p>
</blockquote>
<p>No, definitely not. The result of the first expression is <em>definitely</em> a <code>main.Foo</code>, not a <code>*main.Foo</code>. You made some sort of copy-paste error or the like here.</p></pre>BBfogia: <pre><p>You may try this. It’s been a while since I use this but it should work</p>
<p>f unc Zero(x interface{}) interface{} {
elemValue := reflect.ValueOf(x)
if elemValue.Kind() == reflect.Ptr {
elemValue = reflect.ValueOf(elemValue.Elem().Interface())
}
res := reflect.Zero(elemValue.Type()).Interface()
return res
}</p>
<p><a href="https://github.com/benji-bou/gotools/blob/master/reflectutil/reflectutil.go" rel="nofollow">https://github.com/benji-bou/gotools/blob/master/reflectutil/reflectutil.go</a>
Best</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传