Go – How to create and initialize a struct instance based on conditions when there are multiple custom type structs with the same attributes?

huangapple go评论84阅读模式
英文:

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

你可以通过在PersonAPersonB中嵌入一个共同的结构体来实现这样的操作。

例如(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

huangapple
  • 本文由 发表于 2022年1月20日 06:25:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/70778524.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定