Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 将一个结构复制到另一个结构,其中结构具有相同的成员和不同的类型_Go - Fatal编程技术网

Go 将一个结构复制到另一个结构,其中结构具有相同的成员和不同的类型

Go 将一个结构复制到另一个结构,其中结构具有相同的成员和不同的类型,go,Go,我有两个struct具有相同的成员,我想将一个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

我有两个
struct
具有相同的成员,我想将一个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
}
然后我有struct的
foo
和struct的
bar
,有没有办法从
foo
复制
bar
。以下代码使用转换将
Foo
类型的值复制为
Bar
类型的值:

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


只有在基础类型相同(结构标记除外)的情况下,此选项才有效。

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

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

安装:

go get -u github.com/ulule/deepcopier
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,然后将其解码回目标对象

(gorm的同一作者)也是一个不错的人,我有嵌套结构,我所做的就是:

copier.Copy(员工和用户)


非常有效

如果您想复制或克隆到其他结构,我建议使用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)
    }
输出:
&{Name 12[1 2]123{Field String}[{Field1 String1}{Field2 String2}]}

这是另一个可能的答案

类型公共结构{ 性别智力 从字符串 串 }


你的意图不清楚。你想干什么?酷。显然,这只有在两个结构都具有完全相同的结构时才起作用……但复制到相同的结构是不起作用的type@CeriseLim若要将一个结构复制到另一个实例,转换实际上不会做任何事情,而只是正确地赋值。@JohnWhite这个问题询问不同的类型,这就是我的答案。如果类型没有更改,则不需要进行转换。当类型相同时,答案中的代码确实有效。转换为相同类型时,会生成该类型的新值。这没有用,但它确实起了作用。