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:
Xeoncross:Using reflect.New
[edit] alternatively using reflect.Zero, which might be less allocation (haven't tested). Didn't expect that to work…
TheMerovius:In both examples,
b
is now aninterface{}
according to the compiler so any kind of type checks seem to fail. I tried changing the code toreflect.Zero(reflect.TypeOf(a)).Interface().(Foo)
but then I just have a(*main.Foo)(nil)
that I'm not sure what to do with.
Xeoncross: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 dob := 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/RB5PzuenPY2I'm afraid I don't understand why you don't consider this a full answer of your question?
TheMerovius: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 feedinga
as an*Foo
.Consider this: https://play.golang.org/p/Ok_q3lx490h
BBfogia: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.
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
