Skip to content

0.3.9 no longer merges public fields in embedded structs #139

@mtrmac

Description

@mtrmac

The documentation of Merge includes:

It won't merge unexported (private) fields and will do recursively any exported field.

Yet in 0.3.9:

package main

import (
	"fmt"

	"github.com/imdario/mergo"
)

type inner struct {
	A int
}

type outer struct {
	inner
	B int
}

func main() {
	dst := outer{
		inner: inner{A: 1},
		B:     2,
	}

	src := outer{
		inner: inner{A: 10},
		B:     20,
	}

	err := mergo.MergeWithOverwrite(&dst, src)
	if err != nil {
		panic(err.Error())
	}
	fmt.Printf("%#v\n", dst)
}

and that used to be the case with 0.3.8, returning

main.outer{inner:main.inner{A:10}, B:20}

0.3.9 ignores the embedded struct entirely, returning

main.outer{inner:main.inner{A:1}, B:20}

Using a public name for the inner struct does cause the fields to be merged recursively.

AFAICS this was intentional or at least noticed, #105 (review) points to a test that broke and had to be changed, but there was no further rationale. But that doesn’t really say why this had to change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions