...

Source file src/github.com/imdario/mergo/doc.go

Documentation: github.com/imdario/mergo

     1  // Copyright 2013 Dario Castañé. All rights reserved.
     2  // Copyright 2009 The Go Authors. All rights reserved.
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSE file.
     5  
     6  /*
     7  A helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements.
     8  
     9  Mergo merges same-type structs and maps by setting default values in zero-value fields. Mergo won't merge unexported (private) fields. It will do recursively any exported one. It also won't merge structs inside maps (because they are not addressable using Go reflection).
    10  
    11  Status
    12  
    13  It is ready for production use. It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, etc.
    14  
    15  Important note
    16  
    17  Please keep in mind that a problematic PR broke 0.3.9. We reverted it in 0.3.10. We consider 0.3.10 as stable but not bug-free. . Also, this version adds suppot for go modules.
    18  
    19  Keep in mind that in 0.3.2, Mergo changed Merge() and Map() signatures to support transformers. We added an optional/variadic argument so that it won't break the existing code.
    20  
    21  If you were using Mergo before April 6th, 2015, please check your project works as intended after updating your local copy with go get -u github.com/imdario/mergo. I apologize for any issue caused by its previous behavior and any future bug that Mergo could cause in existing projects after the change (release 0.2.0).
    22  
    23  Install
    24  
    25  Do your usual installation procedure:
    26  
    27      go get github.com/imdario/mergo
    28  
    29      // use in your .go code
    30      import (
    31          "github.com/imdario/mergo"
    32      )
    33  
    34  Usage
    35  
    36  You can only merge same-type structs with exported fields initialized as zero value of their type and same-types maps. Mergo won't merge unexported (private) fields but will do recursively any exported one. It won't merge empty structs value as they are zero values too. Also, maps will be merged recursively except for structs inside maps (because they are not addressable using Go reflection).
    37  
    38  	if err := mergo.Merge(&dst, src); err != nil {
    39  		// ...
    40  	}
    41  
    42  Also, you can merge overwriting values using the transformer WithOverride.
    43  
    44  	if err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil {
    45  		// ...
    46  	}
    47  
    48  Additionally, you can map a map[string]interface{} to a struct (and otherwise, from struct to map), following the same restrictions as in Merge(). Keys are capitalized to find each corresponding exported field.
    49  
    50  	if err := mergo.Map(&dst, srcMap); err != nil {
    51  		// ...
    52  	}
    53  
    54  Warning: if you map a struct to map, it won't do it recursively. Don't expect Mergo to map struct members of your struct as map[string]interface{}. They will be just assigned as values.
    55  
    56  Here is a nice example:
    57  
    58  	package main
    59  
    60  	import (
    61  		"fmt"
    62  		"github.com/imdario/mergo"
    63  	)
    64  
    65  	type Foo struct {
    66  		A string
    67  		B int64
    68  	}
    69  
    70  	func main() {
    71  		src := Foo{
    72  			A: "one",
    73  			B: 2,
    74  		}
    75  		dest := Foo{
    76  			A: "two",
    77  		}
    78  		mergo.Merge(&dest, src)
    79  		fmt.Println(dest)
    80  		// Will print
    81  		// {two 2}
    82  	}
    83  
    84  Transformers
    85  
    86  Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, time.Time is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero time.Time?
    87  
    88  	package main
    89  
    90  	import (
    91  		"fmt"
    92  		"github.com/imdario/mergo"
    93  			"reflect"
    94  			"time"
    95  	)
    96  
    97  	type timeTransformer struct {
    98  	}
    99  
   100  	func (t timeTransformer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {
   101  		if typ == reflect.TypeOf(time.Time{}) {
   102  			return func(dst, src reflect.Value) error {
   103  				if dst.CanSet() {
   104  					isZero := dst.MethodByName("IsZero")
   105  					result := isZero.Call([]reflect.Value{})
   106  					if result[0].Bool() {
   107  						dst.Set(src)
   108  					}
   109  				}
   110  				return nil
   111  			}
   112  		}
   113  		return nil
   114  	}
   115  
   116  	type Snapshot struct {
   117  		Time time.Time
   118  		// ...
   119  	}
   120  
   121  	func main() {
   122  		src := Snapshot{time.Now()}
   123  		dest := Snapshot{}
   124  		mergo.Merge(&dest, src, mergo.WithTransformers(timeTransformer{}))
   125  		fmt.Println(dest)
   126  		// Will print
   127  		// { 2018-01-12 01:15:00 +0000 UTC m=+0.000000001 }
   128  	}
   129  
   130  Contact me
   131  
   132  If I can help you, you have an idea or you are using Mergo in your projects, don't hesitate to drop me a line (or a pull request): https://twitter.com/im_dario
   133  
   134  About
   135  
   136  Written by Dario Castañé: https://da.rio.hn
   137  
   138  License
   139  
   140  BSD 3-Clause license, as Go language.
   141  
   142  */
   143  package mergo
   144  

View as plain text