Struct 用另一个结构指定结构

Struct 用另一个结构指定结构,struct,go,Struct,Go,我有一个RegistrationRequest结构: type RegistrationRequest struct { Email *string Email2 *string Username *string Password *string Name string } 其中Email2是再次输入的电子邮件值,用于验证用户输入的内容是否正确 我还有一个用户结构: type User struct { Emai

我有一个RegistrationRequest结构:

type RegistrationRequest struct {
    Email    *string
    Email2   *string        
    Username *string
    Password *string
    Name     string
}
其中
Email2
是再次输入的电子邮件值,用于验证用户输入的内容是否正确

我还有一个用户结构:

type User struct {
    Email    *string
    Username *string
    Password *string
    Name     string           
}
当然,除了注册之外,无需存储
Email2

所以我有两个变量:
req
u
——每个结构一个。是否可以将
req
结构分配到
u
结构中,以便所有公共字段都存在于
u
结构中?

使用simple you can't,因为即使
User
的字段是
RegistrationRequest
的子集,它们也是完全不同的两种类型,规则不适用

您可以编写一个使用反射(package)的函数,并将所有字段从
req
复制到
u
,但这很难看(而且效率很低)

最好是重构您的类型,
RegistrationRequest
可以
User

如果您具有类型为
RegistrationRequest
的值,则执行此操作意味着您已经具有类型为
User
的值:

type User struct {
    Email    *string
    Username *string
    Password *string
    Name     string
}

type RegistrationRequest struct {
    User  // Embedding User type
    Email2 *string
}

func main() {
    req := RegistrationRequest{}
    s := "as@as.com"
    req.Email = &s

    s2 := "testuser"
    req.Username = &s2

    u := User{}
    u = req.User
    fmt.Println(*u.Username, *u.Email)
}
输出:(在屏幕上尝试)

另外请注意,由于结构包含指针,因此在复制
结构时,指针值将被复制,而不是指针值。我不知道为什么这里需要指针,最好是将所有字段声明为非指针

还要注意的是,嵌入并不是一项真正的要求,它只是使您的类型及其使用更加顺畅<代码>用户
也可以是
请求
的“普通”字段,例如:

type RegistrationRequest struct {
    Usr User // This is just an ordinary field, not embedding
    Email2 *string
}
可以使用“”包在包含相同字段名的结构之间进行复制。这个包使用反射来实现这一点

package main

import (
    "fmt"  
    "github.com/jinzhu/copier"
)

type RegistrationRequest struct {
    Email    *string
    Email2   *string
    Username *string
    Password *string
    Name     string
}

type User struct {
    Email    *string
    Username *string
    Password *string
    Name     string
}

func main() {
    user := new(User)
    req := new(RegistrationRequest)
    user.Email, user.Password, user.Username = new(string), new(string), new(string)
    user.Name = "John Doe"
    *user.Email = "a@b.com"
    *user.Password = "1234"
    *user.Username = "johndoe"
    fmt.Println("User :",user.Name, *user.Email, *user.Username, *user.Password)
    copier.Copy(req, user)
    fmt.Println("RegistrationRequest :",req.Name, *req.Email, *req.Username, *req.Password)
}
输出

 User : John Doe a@b.com johndoe 1234
 RegistrationRequest : John Doe a@b.com johndoe 1234

你是说结构嵌入?很好的方法-这应该适合我。现在开始尝试。附带问题:
注册请求中的
用户
字段-是否“假定”类型为
用户
,因为没有定义任何内容。@tommyd456请阅读其内容。嵌入时,只提供类型,而不提供名称。因此,
User
是类型。
User
的字段被提升到embedder结构。但是您可以使用类型名来引用嵌入值。我知道嵌入是什么。我一直都在提供这两种服务,这似乎很有效,但我也会仔细阅读。我肯定我见过使用名称和类型的示例。@AritraChakraborty那么您将有2个该字段。例如,如果
注册请求
也会有一个
电子邮件字符串
字段,
请求
将必须
电子邮件
字段:一个称为
请求电子邮件
,另一个称为
请求用户电子邮件
。这与OP请求的内容非常接近。如果给出另一个答案,了解copier是否与嵌入式结构一样工作可能会很有用!
 User : John Doe a@b.com johndoe 1234
 RegistrationRequest : John Doe a@b.com johndoe 1234