使用具有不同结构的相同函数的最佳实践 - Golang
Posted
技术标签:
【中文标题】使用具有不同结构的相同函数的最佳实践 - Golang【英文标题】:Best practice to use the same function with different structs - Golang 【发布时间】:2021-11-22 09:13:41 【问题描述】:假设我有不同的结构,它们具有公共字段,并且我想对两者使用相同的 toString 方法。 因为逻辑和流程将完全相同。而且我不想复制它。我正在考虑如何解决这个问题。
type mobile struct
"version" string,
"appName" string
type other struct
"release" string,
"app_name" string
假设我有这两个结构。实际上,版本与发布具有相同的含义。并且 mobile > appName 和 other> app_name 再次具有相同的含义。
所以我想写一个toString
方法来列出这两个对象的详细信息。
func detailsOfMobile(app mobile) string
message := fmt.Sprintf("Here is the details of the *%s* with the version %s", app.appName, app.version)
.....
return message
所以对于其他我需要复制它;
func detailsOfOther (app Ipad) string
message := fmt.Sprintf("Here is the details of the *%s* with the version %s", app.app_name, app.release)
.....
return message
实际上这些方法在现实中要复杂得多。但是我试图留在这里,两个结构都有共同的字段,但它们的命名不同。不重复代码的最佳做法是什么?
【问题讨论】:
“两个结构都有共同的字段,但它们的名称不同”它们唯一的共同点是它们的类型,string
。
最佳实践是复制代码。
【参考方案1】:
您有两种选择,最接近您真正要求的方法是使用界面。您的函数接受一个通用接口,并且您的结构都实现了它:
package main
import (
"fmt"
)
type App interface
Name() string
Version() string
type mobile struct
version string
appName string
func (m mobile) Name() string return m.appName
func (m mobile) Version() string return m.version
type other struct
release string
app_name string
func (o other) Name() string return o.app_name
func (o other) Version() string return o.release
func detailsOfMobile(a App) string
message := fmt.Sprintf("Here is the details of the *%s* with the version %s", a.Name(), a.Version())
return message
func main()
fmt.Println(detailsOfMobile(mobileversion: "1", appName: "iDaft"))
fmt.Println(detailsOfMobile(otherrelease: "2", app_name: "Shazam"))
// Here is the details of the *iDaft* with the version 1
// Here is the details of the *Shazam* with the version 2
作为一种更简单的方法,您也可以让两个结构都实现众所周知的Stringer
接口:
package main
import (
"fmt"
)
type mobile struct
version string
appName string
func (m mobile) String() string
return fmt.Sprintf("%s version %s", m.appName, m.version)
type other struct
release string
app_name string
func (o other) String() string
return fmt.Sprintf("%s release %s", o.app_name, o.release)
func main()
fmt.Println(mobileversion: "1", appName: "iDaft")
fmt.Println(otherrelease: "2", app_name: "Shazam")
// iDaft version 1
// Shazam release 2
【讨论】:
从语言的角度来看这是正确的;但是当我阅读这个问题时,在我看来 OP 不应该使用值引用作为类型定义。定义something with a name and a version
对mobile
、other
、desktop
等都有效。这些引用名称是更通用的type def struct name, version string
的变量
我认为你可能是对的@mh-cbon,很难知道 OP 的简化示例是否丢失了一些关于为什么这些是不同结构的上下文,但肯定像 struct type, name, version string
这样的东西也值得考虑。以上是关于使用具有不同结构的相同函数的最佳实践 - Golang的主要内容,如果未能解决你的问题,请参考以下文章
AWS Cognito:处理相同用户(使用相同电子邮件地址)从不同身份提供商(Google、Facebook)登录的最佳实践
如何为 PostgreSQL 中的自链接记录设计最佳实践数据结构?