Golang将一个结构复制到另一个结构

时间:2016-05-16 03:55:07

标签: go

我有两个struct具有相同的成员,我想将一个结构复制到另一个结构,请参阅下面的伪代码:

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的{​​{1}}和结构Foo的{​​{1}},有没有办法从bar复制Bar

5 个答案:

答案 0 :(得分:20)

使用conversion。以下代码使用转换为将Foo类型的值复制为类型Bar的值:

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

playground example

答案 1 :(得分:2)

如果您想复制或克隆到其他结构,我建议使用deepcopier

它提供了很好的功能,例如跳过,自定义映射和强制。以下是来自github的示例:

安装:

go get -u github.com/ulule/deepcopier

示例:

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: "gilles@example.com",
        },
    }

    resource := &UserResource{}

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

此外,可以通过将源对象编码为JSON,然后将其解码回目标对象的方法来实现。

答案 2 :(得分:1)

这是另一个可能的答案

type Common struct { 性别诠释 从字符串 串 }

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)

答案 3 :(得分:0)

https://github.com/jinzhu/copier(gorm的同一作者)也很不错,我嵌套了结构,而我所做的就是:

copier.Copy(&employees, &user)

效果很好

答案 4 :(得分:0)

如果您想复制或克隆到其他结构,我建议使用Deepcopier

它提供了很好的功能,例如跳过,自定义映射和强制。

您可以按照以下方式实现嵌套结构副本。 安装:

go get -u github.com/ulule/deepcopier

示例:

 package main

    import (
        "fmt"
        "strconv"

        "github.com/ulule/deepcopier"
    )

    //FieldStruct -  Field Struct
    type FieldStruct struct {
        Name string `deepcopier:"field:TargetName"`
        Type string `deepcopier:"field:TargetType"`
    }

    //SourceStruct - Source Struct
    type SourceStruct struct {
        Name        string   `deepcopier:"field:TargetName"`
        Age         int      `deepcopier:"field:TargetAge"`
        StringArray []string `deepcopier:"field:TargetStringArray"`
        StringToInt string   `deepcopier:"context"`
        Field       FieldStruct
        Fields      []FieldStruct
    }

    //TargetFieldStruct -  Field Struct
    type TargetFieldStruct struct {
        TargetName string
        TargetType string
    }

    //TargetStruct - Target Struct
    type TargetStruct struct {
        TargetName        string
        TargetAge         int
        TargetStringArray []string
        TargetInt         int
        TargetField       TargetFieldStruct
        TargetFields      []TargetFieldStruct
    }

    //write methods

    //TargetInt - StringToInt
    func (s *SourceStruct) TargetInt() int {
        i, _ := strconv.Atoi(s.StringToInt)
        return i
    }

    func main() {
        s := &SourceStruct{
            Name:        "Name",
            Age:         12,
            StringArray: []string{"1", "2"},
            StringToInt: "123",
            Field: FieldStruct{
                Name: "Field",
                Type: "String",
            },
            Fields: []FieldStruct{
                FieldStruct{
                    Name: "Field1",
                    Type: "String1",
                },
                FieldStruct{
                    Name: "Field2",
                    Type: "String2",
                },
            },
        }

        t := &TargetStruct{}

        //coping data into inner struct
        deepcopier.Copy(&t.TargetField).From(&s.Field)

        // copied array of Struct
        for i := range s.Fields {
            // init a struct
            t.TargetFields = append(t.TargetFields, TargetFieldStruct{})
            // coping the data
            deepcopier.Copy(&t.TargetFields[i]).From(&s.Fields[i])
        }
        //Top level copy
        deepcopier.Copy(t).From(s)

        fmt.Println(t)
    }

输出: &{名称12 [1 2] 123 {字段字符串} [{Field1 String1} {Field2 String2}]}