Go中函数重载的替代方案?

Posted

技术标签:

【中文标题】Go中函数重载的替代方案?【英文标题】:Alternative for function overloading in Go? 【发布时间】:2012-10-13 06:28:06 【问题描述】:

是否可以像使用 Golang 的 C# 中的函数重载或可选参数一样工作?或者也许是另一种方式?

【问题讨论】:

你能举一个具体的例子(也在c#中)你想做什么? public void Compresser(string dstFilePath, string srcFilePath, string fileName) public void Compresser(string srcFilePath, string fileName) 可能重复:***.com/questions/2032149/optional-parameters Go 中的 func Compress(srcFilePath string, fileName string)func CompressInto(dstFilePath string, srcFilePath string, fileName string) 【参考方案1】:

Go 中可选参数的惯用答案是包装函数:

func do(a, b, c int) 
    // ...


func doSimply(a, b) 
    do(a, b, 42)

函数重载被有意遗漏了,因为它使代码难以阅读。

【讨论】:

因为它使代码难以阅读。 这完全是主观的。我不这么认为,并非总是如此。 @old_mountain 我相信围棋设计师同意你的观点,有时更难,有时更容易。然而,从经验上看,他们认为使用不当的案例远远多于使用良好的案例。所以总的来说,删除它们会使代码更容易阅读。请记住,设计师拥有数十年的行业定义经验。 Go Playground 示例play.golang.org/p/7znCwjK6zIp +1。 @JonathanHartley 你用更主观的东西超越了它。 “从字面上定义行业”几乎是一个悖论。一个人只需要定义一些新的东西,如果我们谈论的是一个现有的行业,为什么要定义它? Go 似乎做了很多这样的假设,这对任何人都没有帮助。糟糕的编码员会写出糟糕的代码,或者选择让他们这样做的糟糕的框架。当语言试图优化性能时,为糟糕的编码人员进行优化是(主观的)一个糟糕的选择。 @Rads 是的,这很公平。请记住,我正在回复一条已被删除的评论,我推测这很离谱。【参考方案2】:

既不直接支持函数重载,也不支持可选参数。您可以围绕它们构建自己的参数结构。我的意思是这样(未经测试,可能无法正常工作......)编辑:now tested...

package main

    import "fmt"

    func main() 
        args:=NewMyArgs("a","b") // filename is by default "c"
        args.SetFileName("k")

        ret := Compresser(args)
        fmt.Println(ret)
    

    func Compresser(args *MyArgs) string 
        return args.dstFilePath + args.srcFilePath + args.fileName 
    

    // a struct with your arguments
    type MyArgs struct 
    
        dstFilePath, srcFilePath, fileName string 
    

   // a "constructor" func that gives default values to args 
    func NewMyArgs(dstFilePath string, srcFilePath string) *MyArgs 
        return &MyArgs
              dstFilePath: dstFilePath, 
              srcFilePath:srcFilePath, 
              fileName :"c"
    

    func (a *MyArgs) SetFileName(value string)
      a.fileName=value;
    

【讨论】:

Go 中现在允许使用可选参数。看看这个changelog.ca/log/2015/01/30/golang @MohitBhura 您的链接值得一读,但它并没有说现在允许可选参数。事实上,它提出了一种不同的方法来解决它们的缺失,基于空接口和可变参数【参考方案3】:

有一些提示here使用可变参数,例如:

sm1 := Sum(1, 2, 3, 4) // = 1 + 2 + 3 + 4 = 10
sm2 := Sum(1, 2) // = 1 + 2 = 3
sm3 := Sum(7, 1, -2, 0, 18) // = 7 + 1 + -2 + 0 + 18 = 24
sm4 := Sum() // = 0

func Sum(numbers ...int) int     
    n := 0    
    for _,number := range numbers 
        n += number
        
    return n

...interface 用于任何类型:

Ul("apple", 7.2, "BANANA", 5, "cHeRy")

func Ul(things ...interface) 
  fmt.Println("<ul>")    
  for _,it := range things 
    fmt.Printf("    <li>%v</li>\n", it)
      
  fmt.Println("</ul>")

【讨论】:

【参考方案4】:

我有时使用具有不同参数的新方法构造对象的方法是具有“风味”伪类型。你可以在 Go Playground 上试一试https://play.golang.org/p/5To5AcY-MRe

package main

import "fmt"

type flavorA struct
type flavorB struct

var FlavorA = flavorA
var FlavorB = flavorB

type Something struct 
    i int
    f float64


func (flavor flavorA) NewSomething(i int) *Something 
    return &Somethingi:i, f:0.0


func (flavor flavorB) NewSomething(f float64) *Something 
    return &Somethingi:0, f:f


func main() 
    fmt.Println(FlavorA.NewSomething(1), FlavorB.NewSomething(2))

【讨论】:

这个没有意义,和func FlavorANewSomething()没有区别

以上是关于Go中函数重载的替代方案?的主要内容,如果未能解决你的问题,请参考以下文章

Go语言的特性

Go语言的特性

具有替代方法的重载方法 foreachBatch

如果我在 Scala 中定义多个重载构造函数,我不能定义默认值吗?

Scala:方法的多个重载替代方案

Scala - 处理“方法的多个重载替代方案......定义默认参数”