使用具有不同结构的相同函数的最佳实践 - 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 versionmobileotherdesktop 等都有效。这些引用名称是更通用的type def struct name, version string 的变量 我认为你可能是对的@mh-cbon,很难知道 OP 的简化示例是否丢失了一些关于为什么这些是不同结构的上下文,但肯定像 struct type, name, version string 这样的东西也值得考虑。

以上是关于使用具有不同结构的相同函数的最佳实践 - Golang的主要内容,如果未能解决你的问题,请参考以下文章

最佳实践:多次使用相同的着色器

AWS Cognito:处理相同用户(使用相同电子邮件地址)从不同身份提供商(Google、Facebook)登录的最佳实践

如何为 PostgreSQL 中的自链接记录设计最佳实践数据结构?

在 ASP.NET MVC 项目中设置具有不同帐户和视图的多个公司的最佳实践

登录python的最佳实践

将两个不同的网格放在同一个顶点 VBO 中的 OpenGL 最佳实践