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

xuanbao · 2018-03-01 04:30:10 · 566 次点击    
这是一个分享于 2018-03-01 04:30:10 的资源,其中的信息可能已经有所发展或是发生改变。

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: https://play.golang.org/p/7XcrhoTHejn


评论:

TheMerovius:

Using reflect.New

[edit] alternatively using reflect.Zero, which might be less allocation (haven't tested). Didn't expect that to work…

Xeoncross:

In both examples, b is now an interface{} according to the compiler so any kind of type checks seem to fail. I tried changing the code to reflect.Zero(reflect.TypeOf(a)).Interface().(Foo) but then I just have a (*main.Foo)(nil) that I'm not sure what to do with.

TheMerovius:

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 b := (someExpresion).(Foo), you can also just do b := Foo{} and be done with it.

And both the examples that I posted provide you with an empty main.Foo, not (*main.Foo)(nil), 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): https://play.golang.org/p/QxUwwfr29xz https://play.golang.org/p/RB5PzuenPY2

I'm afraid I don't understand why you don't consider this a full answer of your question?

Xeoncross:

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.

The reason I am getting back a main.Foo or (main.Foo)(nil) is because I'm feeding a as an *Foo.

Consider this: https://play.golang.org/p/Ok_q3lx490h

TheMerovius:

I tried changing the code to reflect.Zero(reflect.TypeOf(a)).Interface().(Foo) but then I just have a (*main.Foo)(nil)

No, definitely not. The result of the first expression is definitely a main.Foo, not a *main.Foo. You made some sort of copy-paste error or the like here.

BBfogia:

You may try this. It’s been a while since I use this but it should work

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 }

https://github.com/benji-bou/gotools/blob/master/reflectutil/reflectutil.go Best


入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

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