Golang – best practice for using same function for two structs with same field

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

Golang - best practice for using same function for two structs with same field

问题

假设我有以下两个结构体:

type Game struct {
	Name string
	MultiplayerSupport bool
	Genre string
	Version string
}

type ERP struct {
	Name string
	MRPSupport bool
	SupportedDatabases []string
	Version string
}

我想要为这些结构体附加一个打印Version变量的函数:

func (e *ERP) PrintVersion()  {
	fmt.Println("Version is", e.Version)
}

我知道可以使用接口,但是我仍然需要为这两个结构体定义两个相同的函数,这样会导致代码重复。

在这种情况下,有什么最佳实践可以避免代码重复?

附注:在你标记为“这个问题已经在这里有答案了”的之前,请注意,这个问题与下面的问题不同,因为这两个结构体之间的字段名称不同。

https://stackoverflow.com/questions/69393728/best-practice-to-use-the-same-function-with-different-structs-golang

英文:

Imagine I have these two structs:

type Game struct {
	Name string
	MultiplayerSupport bool
	Genre string
	Version string
}

type ERP struct {
	Name string
	MRPSupport bool
	SupportedDatabases []string
	Version string
}

I want a function attached to these structs that will print the Version variable

func (e *ERP) PrintVersion()  {
	fmt.Println("Version is", e.Version)
}

I know I can use an interface, but I still have to define two identical functions for both of the structs, which is code repetition.

What is the best practice here to prevent code repetition?

P.S. Before you flag it with "This question already has an aswer here", it is not the same question since on following question, field names between the structs differ.

https://stackoverflow.com/questions/69393728/best-practice-to-use-the-same-function-with-different-structs-golang

答案1

得分: 4

在准备问题的过程中,我想到可以实现类似这样的东西:

type Version string

func (v Version) PrintVersion() {
	fmt.Println("Version is", v)
}

因为所有自定义类型(不仅仅是结构体)都可以作为方法接收者。

然后我可以在结构体中使用这个类型,使用组合

type Game struct {
	Name               string
	MultiplayerSupport bool
	Genre              string
	Version
}

type ERP struct {
	Name               string
	MRPSupport         bool
	SupportedDatabases []string
	Version
}

然后我可以像使用普通字符串字段一样使用它(实际上它就是一个字符串字段!)

func main() {

	g := Game{
		"Fear Effect",
		false,
		"Action-Adventure",
		"1.0.0",
	}

	g.PrintVersion()
    // Version is 1.0.0


	e := ERP{
		"Logo",
		true,
		[]string{"ms-sql"},
		"2.0.0",
	}

	e.PrintVersion()
    // Version is 2.0.0

}
英文:

While I was preparing the question, it occured to me that I can implement something like this:

type Version string

func (v Version) PrintVersion() {
	fmt.Println("Version is", v)
}

Since all custom types (not only structs) can be method receivers.

Then I can use this type on the structs using composition:

type Game struct {
	Name               string
	MultiplayerSupport bool
	Genre              string
	Version
}

type ERP struct {
	Name               string
	MRPSupport         bool
	SupportedDatabases []string
	Version
}

Then I can use it just like a normal string field (which indeed it is!)

func main() {

	g := Game{
		"Fear Effect",
		false,
		"Action-Adventure",
		"1.0.0",
	}

	g.PrintVersion()
    // Version is 1.0.0


	e := ERP{
		"Logo",
		true,
		[]string{"ms-sql"},
		"2.0.0",
	}

	e.PrintVersion()
    // Version is 2.0.0

}

huangapple
  • 本文由 发表于 2022年10月30日 15:38:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/74251278.html
匿名

发表评论

匿名网友

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

确定