How do you get a new, empty copy of an unknown struct?

xuanbao · · 446 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I want to clone a struct. I have no foreknowledge of it&#39;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&#39;t tested). Didn&#39;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&#39;m not sure what to do with.</p></pre>TheMerovius: <pre><p>I don&#39;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&#39;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&#39;m afraid I don&#39;t understand why you don&#39;t consider this a full answer of your question?</p></pre>Xeoncross: <pre><p>I&#39;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&#39;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

446 次点击  
加入收藏 微博
0 回复
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传