-
-
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
nested non-addressable values cannot be merged #162
Comments
Thanks for opening a new issue. The team has been notified and will review it as soon as possible. |
Adding this to v2 backlog. |
My issue was closed in favor of this one. If it is valuable I had written a testcase #168 that could be cherry-picked. Just noting this because that PR got automatically closed as well. |
@dionysius No new features or default behaviours will be added to v1. I'll publish in a few minutes an updated README stating this. |
nested non-addressable values cannot be merged
My specific problem is this: given two structs with interface{} fields that contain struct values of the same type, the interface{} fields are not deeply merged.
expected value of dst:
actual value of dst:
The reason for this is that merge.go:267 calls deepMerge with the interface values (
[value].Elem()
). However, since those are values in a field of type interface{}, they're not addressable (did not expect that, learned something today). The recursive call will end up in the default case of that switch statement, and on line merge.go:275, CanSet() will be false (because CanAddr() is false), and you'll try assigningdst = src
.But there's a problem with that. dst is of type reflect.Value, which is not merely a Value, it's a value. It's not a pointer. That assignment can't modify any memory outside of that method. As soon as the argument for deepMerge, dst, stops being addressable, deepMerge can no longer modify dst, which is its implicit return value. It may as well return immediately.
deepMerge used to return
(dst reflect.Value, err error)
. It was changed recently, and I'm not sure why. The change, unfortunately, prevents me from deeply merging equal values in interfaces, as appears to be the intent of merge.go:266-271. Would you be open to going back to returning (dst, err) so that dst can be set back up at the interface level where it's still addressable? If you are ok with that change, I'm happy to make a pull request for it!All files and line numbers as of v0.3.11
Upvote & Fund
The text was updated successfully, but these errors were encountered: