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

jsv*_*isa 21 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
}
Run Code Online (Sandbox Code Playgroud)

然后,我有foo结构的Foo,而bar结构的Bar,有什么办法复制barfoo

Cer*_*món 31

使用转化.以下代码使用转换为将类型Foo的值复制到类型的值Bar:

foo := Foo{Id: "123", Name: "Joe"}
bar := Bar(foo)
Run Code Online (Sandbox Code Playgroud)

操场的例子

  • 凉.显然这只有两个结构具有完全相同的结构才有效. (4认同)
  • ..但是复制到相同的结构类型是行不通的 (2认同)

mel*_*ngs 7

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

copier.Copy(&employees, &user)

效果很好


Muh*_*man 6

如果您想复制或克隆到不同的结构,我建议使用deepcopier

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

安装:

go get -u github.com/ulule/deepcopier
Run Code Online (Sandbox Code Playgroud)

例子:

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
}
Run Code Online (Sandbox Code Playgroud)

此外,您还可以通过将源对象编码为 JSON,然后将其解码回目标对象来实现这一点。


Dam*_*nda 6

这是另一个可能的答案

type Common struct { Gender int 从字符串到字符串 }

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)
Run Code Online (Sandbox Code Playgroud)