英文:
How to reuse struct keys on golang?
问题
有没有办法将一个结构体的键用于另一个结构体?
例如,我有以下结构体:
type Player struct {
Age uint8 `json:"age"`
Name string `json:"name"`
UUID string `json:"uuid"`
}
type PlayerDynamo struct {
// 我希望将Player的所有键与`Salary`处于同一级别。
// Age uint8 `json:"age"`
// Name string `json:"name"`
// UUID string `json:"uuid"`
Salary float32 `json:"salary"`
}
如何声明PlayerDynamo
以使用与Player
相同的键?
英文:
Is there a way to use the keys from a struct into another struct?
For example I have the following struct:
type Player struct {
Age uint8 `json:"age"`
Name string `json:"name"`
UUID string `json:"uuid"`
}
type PlayerDynamo struct {
// I want all the keys from Player at the same level as `Salary`.
// Age uint8 `json:"age"`
// Name string `json:"name"`
// UUID string `json:"uuid"`
Salary float32 `json:"salary"`
}
How could I declare PlayerDynamo
to use the same keys as Player
?
答案1
得分: 7
Go支持一种独特的特性,称为"结构体嵌入"或者只是"嵌入",这是一种一流的组合方式(与大多数面向对象编程语言提供的一流继承相比)。
嵌入允许你在一个结构体中嵌入另一个结构体,这样嵌入结构体的成员可以像在父结构体上声明的一样被引用:
type Player struct {
Age uint8 `json:"age"`
Name string `json:"name"`
UUID string `json:"uuid"`
}
type PlayerDynamo struct {
Player // PlayerDynamo "嵌入" Player
Salary float32 `json:"salary"`
}
现在,PlayerDynamo
的实例既有一个Player
成员...
p := PlayerDynamo{}
p.Player.Name
又有Player
的嵌入字段:
p := PlayerDynamo{}
p.Name // 等同于 p.Player.Name
甚至可以在PlayerDynamo
上调用Player
的方法:
func (p Player) String() string {
return fmt.Sprintf("Player %q", p.Name)
}
p := PlayerDynamo{
Player: Player {
Name: "Bob",
},
}
fmt.Println(p.String()) // Player "Bob"
这并不完全等同于将Age
/Name
/UUID
字段复制到PlayerDynamo
中:当你声明一个新的PlayerDynamo
时,仍然需要显式地初始化嵌入的Player
:
p := PlayerDynamo {
Player: Player {
Name: "test",
Age: 45,
},
Salary: 42,
}
关键是,结构体标签会被复制过来,将结构体编组为JSON时,所有的Player
字段都会出现在PlayerDynamo
的编组表示中。
请参考https://play.golang.org/p/6HMrlVZzIsn 查看一个实时示例。
英文:
Go supports a somewhat unique feature called "struct embedding" or just "embedding", a type of first-class composition (vs what most OOP languages offer, first-class inheritance).
Embedding allows you to embed one struct within another, such that the members of the embedded struct can be referenced as though they were declared on the parent structure:
type Player struct {
Age uint8 `json:"age"`
Name string `json:"name"`
UUID string `json:"uuid"`
}
type PlayerDynamo struct {
Player // PlayerDynamo "embeds" Player
Salary float32 `json:"salary"`
}
An instance of a PlayerDynamo
now has both a Player
member...
p := PlayerDynamo{}
p.Player.Name
and the embedded fields of Player
:
p := PlayerDynamo{}
p.Name // Equivalent to p.Player.Name
Even methods of Player
can be invoked on a PlayerDynamo
:
func (p Player) String() string {
return fmt.Sprintf("Player %q", p.Name)
}
p := PlayerDynamo{
Player: Player {
Name: "Bob",
},
}
fmt.Println(p.String()) // Player "Bob"
This isn't exactly the same as copying the Age
/Name
/UUID
fields into the PlayerDynamo
: When you declare a new PlayerDynamo
, you still need to initialize the embedded Player
explicitly:
p := PlayerDynamo {
Player: Player {
Name: "test",
Age: 45,
}
Salary: 42
}
Critically, the struct tags are copied over and marshalling to JSON works as expected, with all of the Player
fields appearing within the marshalled representation of a PlayerDynamo
.
See https://play.golang.org/p/6HMrlVZzIsn for a live example.
答案2
得分: 0
使用嵌入式结构:
type PlayerDynamo struct {
Player
Salary float32 `json:"salary"`
}
英文:
Use embedding:
type PlayerDynamo struct {
Player
Salary float32 `json:"salary"`
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论