英文:
Go - How to create and initialize a struct instance based on conditions when there are multiple custom type structs with the same attributes?
问题
我对Go还不太熟悉,现在面临一个需要帮助的情况。
假设有两种具有相同属性列表的结构体:
type PersonA struct {
[很长的属性列表...]
}
type PersonB struct {
[相同的很长的属性列表...]
}
我想根据一些条件创建一个实例并进行初始化,像下面这样:
var smartPerson [类型]
func smartAction(personType string) {
switch personType
case "A":
smartPerson = PersonA{很长的属性列表初始化}
case "B":
smartPerson = PersonB{相同的很长的属性列表初始化}
}
fmt.Println(smartPerson)
这里有两个问题:
首先,'smartPerson'需要在switch语句中确定实例类型。
其次,'很长的属性列表初始化'在所有条件下都是相同的,最好避免重复。
在Go中是否可以实现这个需求?
英文:
I'm still new to Go and am facing a situation that needs some help here.
Assume there are two types of structs with the SAME attribute list:
type PersonA struct {
[long list of attributes...]
}
type PersonB struct {
[same long list of attributes...]
}
And I would like to create an instance and initialize based on some conditions like below:
var smartPerson [type]
func smartAction(personType string) {
switch personType
case "A":
smartPerson = PersonA{long list initialization}
case "B":
smartPerson = PersonB{same long list initialization}
}
fmt.Println(smartPerson)
There are two problems here:
First - 'smartPerson' needs to be the instance type ascertained in the switch statement.
Second - the 'long list initialization' is the same for all conditions, so better to avoid repetition.
Is it possible to do this in Go?
答案1
得分: 2
你可以通过在PersonA
和PersonB
中嵌入一个共同的结构体来实现这样的操作。
例如(playground链接):
package main
import "fmt"
type commonPerson struct {
A string
B string
C string
}
type PersonA struct {
commonPerson
}
func (p PersonA) String() string {
return fmt.Sprintf("A: %s, %s, %s", p.A, p.B, p.C)
}
// 这个函数只是为了让PersonA实现personInterface接口
func (p PersonA) personMarker() {}
type PersonB struct {
commonPerson
}
func (p PersonB) String() string {
return fmt.Sprintf("B: %s, %s, %s", p.A, p.B, p.C)
}
// 这个函数只是为了让PersonB实现personInterface接口
func (p PersonB) personMarker() {}
type personInterface interface {
personMarker()
}
var smartPerson personInterface
func smartAction(personType string) {
common := commonPerson{
A: "foo",
B: "bar",
C: "Hello World",
}
switch personType {
case "A":
smartPerson = PersonA{commonPerson: common}
case "B":
smartPerson = PersonB{commonPerson: common}
}
}
func main() {
smartAction("A")
fmt.Println(smartPerson)
smartAction("B")
fmt.Println(smartPerson)
}
输出:
A: foo, bar, Hello World
B: foo, bar, Hello World
英文:
You can, do something like this by embedding a common struct in both PersonA
and PersonB
.
For example (playgound link):
package main
import "fmt"
type commonPerson struct {
A string
B string
C string
}
type PersonA struct {
commonPerson
}
func (p PersonA) String() string {
return fmt.Sprintf("A: %s, %s, %s", p.A, p.B, p.C)
}
// This function is just here so that PersonA implements personInterface
func (p PersonA) personMarker() {}
type PersonB struct {
commonPerson
}
func (p PersonB) String() string {
return fmt.Sprintf("B: %s, %s, %s", p.A, p.B, p.C)
}
// This function is just here so that PersonB implements personInterface
func (p PersonB) personMarker() {}
type personInterface interface {
personMarker()
}
var smartPerson personInterface
func smartAction(personType string) {
common := commonPerson{
A: "foo",
B: "bar",
C: "Hello World",
}
switch personType {
case "A":
smartPerson = PersonA{commonPerson: common}
case "B":
smartPerson = PersonB{commonPerson: common}
}
}
func main() {
smartAction("A")
fmt.Println(smartPerson)
smartAction("B")
fmt.Println(smartPerson)
}
Outputs:
A: foo, bar, Hello World
B: foo, bar, Hello World
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论