Go语言 如何将结构字段用于另一个结构而不将其作为键引用

cnh2zyt3  于 2022-12-16  发布在  Go
关注(0)|答案(1)|浏览(145)

我想将一个结构字段插入到另一个结构中,而不必使用结构名。

我知道我能做到

type Person struct {
  Name string
}

type User struct {
  Person
  Email, Password string
}

但它会产生以下结构:

user := User{Person: Person{Name: ""}, Email: "", Password: ""}

我该怎么做

type Person struct {
  Name string
}

type User struct {
  Name Person.Name // Here
  Email, Password string
}

"像这样使用它"

user := User{Name: "", Email: "", Password: ""}

"这可能吗"

fkvaft9z

fkvaft9z1#

简单地说,使用当前的语言实现是不行的。
当初始化一个常量时,你需要显式地(或者,换句话说:literal![sic])。由于User包含Person,因此literal User必须包含literal Person,如您所示:

u := User{ 
        Person: Person{
            Name: "Bob",
        },
        Email: "bob@bobspot.com",
        Password: "you're kidding right?",
    }

但是,一旦您有了User类型的 * 变量 *,您就可以利用anonymous字段来设置(或获取)匿名PersonName,其中包含User

u := User{}
    u.Name = "Bob"
    u.Email = "bob@bobspot.com",
    u.Password = "you're kidding right?",

为什么Go让我做所有这些工作?
让我们想象一下,它是可能的初始化内部Person的方式,你正在寻找:

u := User{ Name: "Bob" }

现在让我们进一步想象一下,我们稍后修改了User结构体并 * 添加 * 了它自己的Name字段:

type User struct {
        Person
        Name string
        Email string
        Password string
    }

现在,您显然可以初始化新的Name字段:

u := User{ Name: "Bob" }

注意,这与之前初始化User.Person.Name的代码相同,但现在它正在初始化User.Name

更多陷阱

类似这样的代码还隐藏着更多的陷阱。
首先,在User中添加Name字段 * 已经 * 类似地“中断”了User变量上对Name的非限定引用:

u.Name = "Bob" // used to set User.Person.Name, now sets User.Name

此外,由于只有一个匿名Person字段,User.Person.Name字段在默认情况下作为“Name”字段被编组到JSON:

{
        "Name": "",
        "Email": "",
        "Password": ""
    }

如果添加了Name字段,则 this 是被编组为"Name"的字段,而User.Person.Name字段 * 根本 * 不被编组。
您可能认为可以为User.Person.Name添加一个json标记,例如

type User struct {
        Person   `json:"PersonName"`
        Name     string
        Email    string
        Password string
    }

但是 * 现在 * Person被编组为一个 * 对象 *,其中包含一个Name字段:

{
        "PersonName": {
            "Name": ""
        },
        "Name": "",
        "Email": "",
        "Password": ""
    }
  • 即使User没有Name字段 *,如果您试图更改匿名Person的编组字段名,也会发生这种情况。

简而言之:在structs* 中使用anonymous *structs作为“添加字段”的一种方式可能会有问题,而且很脆弱,应该尽量避免。

相关问题