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

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.


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


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.


This is another possible answer

type Common struct { Gender int From string To string }

type Foo struct {
    Id    string
    Name  string
    Extra Common
}

type Bar struct {
    Id    string
    Name  string
    Extra Common
}
foo:=Foo{
    Id:"123",
    Name:"damitha",
    Extra: struct {
        Gender int
        From   string
        To     string
    }{Gender:1 , From:"xx", To:"yy" },
}
bar:=*(*Bar)(unsafe.Pointer(&foo))
fmt.Printf("%+v\n",bar)