-
-
Notifications
You must be signed in to change notification settings - Fork 271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unexpected outcomes while trying to merge two instances of type reflect.Value #159
Comments
Thanks for opening a new issue. The team has been notified and will review it as soon as possible. |
I'm not sure trying to merge reflect.Value is the safest option. It seems to be mergeable because the struct contains a pointer to the underlying data, but it feels like you are relying on an internal implementation detail for that, which is usually a bad idea. I would go for the code in your second link, it looks clearer and less magic. Anyway, I will take this into account in the next big version of Mergo, written from scratch. If you provide a PR for the current version, I won't mind reviewing and merging it. |
The sample code is definitely not going to do what you want as provided, mostly because you don't actually want to merge go's internal reflect.Value structs. You actually want to merge the things in those reflect.Value structs. That's possible, but it would take a fair bit of work. Ultimately, it's imdario's call, but it sounds like he considers this out-of-scope. In more detail: The obvious thing to try would be to call .Interface() on your reflect.Value before passing it into mergo. That could work, but it doesn't for a couple reasons:
If you could get all that working, then you could lift it into the package and support reflect.Value as a valid input type. I personally wouldn't go that far, but not my decision |
@bionoren Thanks for your insightful comment. This is something I'm willing to support in the next major version, but I don't have a defined ETA for it. Currently, it's hard to add changes. The cognitive load of the code is above what I can handle properly. This is an undesired byproduct of my liberal policy of accepting PRs, and trying to keep it as flexible as possible. |
Just wanted to circle back on this. I was able to change the code in the original post to make it behave as desired. The problem seemed to be making an unnecessary call to the reflect Value's Elem method, which was essentially dereferencing the underlying pointer type. I would like to point out that, documented or not, this library seems to gladly accept interface{} types in the Merge function as long as the reflect kind is a pointer to a struct (maybe pointer to map works too, I didn't try). Simple illustration here. In any case, altering the original author's code to pass the non-dereferenced, interface{}-casted values to the Merge function, along with some compensating changes, was enough to get it to behave as desired: https://play.golang.org/p/_r3fc_UikdX |
https://play.golang.org/p/Jewi51WT-gZ
The expected outcome here is:
but we get:
which means if the dest has no value provided, the value from src will be used.
I tried this with a few different versions of the library: specifically 0.3.7, 0.3.8 & 0.3.10. Got the same response in all cases.
Although, with the version 0.3.9, I got a different response, still incorrect
The field value from the base is preserved, but the slice value from override is lost.
We don't see this issue if the values are converted to respective structs first and then invoke
mergo.Merge
: https://play.golang.org/p/t-ND1sobjUbWe get the expected outcome in this case.
The text was updated successfully, but these errors were encountered: