Documentation ¶
Overview ¶
Package merger can merge different Go types together.
This can be useful for:
- Merging configurations from different sources
- Deduplicate items before serialization
- Setting field preferences
Merge Algorithm ¶
Let A be the first arbitrary value and B be the second arbitrary value with precedence.
boolean, numeric and string types will be overwritten by the argument with precedence (B). slice and array types will be concatenated (A ∥ B). struct and map types will be merged together giving a union of all fields, where the values of them are merged too (A ∪ B)
Merge Examples ¶
Merging boolean, numeric, string types (overwrite):
A := "a" B := 4 V, _ := merger.Merge(A, B) // V: 4
Merging map, struct types (union):
A := map[string]int{ "x": 1, "y": 2, } B := map[string]int{ "a": 1, "b": 2, } V, _ := merger.Merge(A, B) // V: map[string]int{"a": 1, "b": 2, "x": 1, "y": 2}
Merging slice, array types (concat):
A := []int{1, 2, 3} B := []int{4, 5, 6} V, _ := merger.Merge(A, B) // V: []int{1, 2, 3, 4, 5, 6}
Merging embedded types:
A := map[string]interface{}{ "a": []int{1, 2}, "b": "aAaAaA", "c": map[int]int{1: 10, 2: 20}, } B := map[string]interface{}{ "a": []int{3, 4}, "b": "bBbBbB", "c": map[int]int{1: 100, 3: 30}, } V, _ := merger.Merge(A, B) // V: map[string]interface{}{"a": []int{1,2,3,4}, "b": "bBbBbB", "c": map[int]int{1:100, 2:20, 3:30}}
Index ¶
Examples ¶
Constants ¶
const ( ErrDiffKind = 1 << iota ErrMergeUnsupported = 1 << iota ErrInvalidFields = 1 << iota ErrDiffArrayTypes = 1 << iota ErrDiffSliceTypes = 1 << iota ErrDiffMapKeyTypes = 1 << iota ErrDiffMapValueTypes = 1 << iota )
MergeError types with value 2ⁿ
Variables ¶
This section is empty.
Functions ¶
func Merge ¶
func Merge(a interface{}, b interface{}) (interface{}, error)
Merge merges a and b together where b has precedence. It is not destructive on their parameters, but these must not be modified while merge is in progress.
Example ¶
// Create struct A A := struct { FieldA string FieldB string FieldC []int }{ "aAaA", "bBbB", []int{1, 2}, } // Create struct B B := struct { FieldA string FieldC []int }{ "NewVal", []int{3, 4}, } // Merge struct A and B together V, err := Merge(A, B) if err != nil { log.Fatal(err) } // Serialize ser, _ := json.Marshal(V) fmt.Println(string(ser))
Output: {"FieldA":"NewVal","FieldB":"bBbB","FieldC":[1,2,3,4]}
Example (Nested) ¶
// Create two maps with nested types A := map[string]interface{}{ "a": []int{1, 2}, "b": "aAaAaA", "c": map[int]int{1: 10, 2: 20}, } B := map[string]interface{}{ "a": []int{3, 4}, "b": "bBbBbB", "c": map[int]int{1: 100, 3: 30}, "d": "Only in B", } // Merge map A and B together, including their values V, err := Merge(A, B) if err != nil { log.Fatal(err) } // Serialize ser, _ := json.Marshal(V) fmt.Println(string(ser))
Output: {"a":[1,2,3,4],"b":"bBbBbB","c":{"1":100,"2":20,"3":30},"d":"Only in B"}
Types ¶
type MergeError ¶
type MergeError struct {
// contains filtered or unexported fields
}
MergeError represents an error which has occurred while merging
func (*MergeError) Error ¶
func (e *MergeError) Error() string
func (*MergeError) Type ¶
func (e *MergeError) Type() int
Type returns the MergeError type which is one or multiple of Err constants by 2ⁿ
Notes ¶
Bugs ¶
When merging structs fields are appended (A.Fields ∥ B.Fields). But field types should be taken from b as it has precedence.