Copy one struct to another where structs have same members and different types

If you would like to copy or clone to a different struct, I would suggest using deepcopier

It provides nice features like skipping, custom mapping, and forcing. below is an example from github:

Install:

go get -u github.com/ulule/deepcopier

Example:

package main

import (
    "fmt"

    "github.com/ulule/deepcopier"
)

// Model
type User struct {
    // Basic string field
    Name  string
    // Deepcopier supports https://golang.org/pkg/database/sql/driver/#Valuer
    Email sql.NullString
}

func (u *User) MethodThatTakesContext(ctx map[string]interface{}) string {
    // do whatever you want
    return "hello from this method"
}

// Resource
type UserResource struct {
    //copy from field "Name"
    DisplayName            string `deepcopier:"field:Name"`
    //this will be skipped in copy 
    SkipMe                 string `deepcopier:"skip"`
    //this should call method named MethodThatTakesContext 
    MethodThatTakesContext string `deepcopier:"context"`
    Email                  string `deepcopier:"force"`

}

func main() {
    user := &User{
        Name: "gilles",
        Email: sql.NullString{
            Valid: true,
            String: "[email protected]",
        },
    }

    resource := &UserResource{}

    deepcopier.Copy(user).To(resource)
    //copied from User's Name field
    fmt.Println(resource.DisplayName)//output: gilles
    fmt.Println(resource.Email) //output: [email protected]
    fmt.Println(resource.MethodThatTakesContext) //output: hello from this method
}

Also, some other way you could achieve this is by encoding the source object to JSON and then decode it back to the destination object.


https://github.com/jinzhu/copier (same author of gorm) is also quite a good one, I have nested structs and all I do is:

copier.Copy(&employees, &user)

works great


Use a conversion to change the type. The following code uses a conversion to copy a value of type Foo to a value of type Bar:

foo := Foo{Id: "123", Name: "Joe"}
bar := Bar(foo)

playground example

The conversion only works when the underlying types are identical except for struct tags.

Tags:

Go