Go方法中的默认值

den*_*iss 61 go

有没有办法在Go的函数中指定默认值?我试图在文档中找到这个,但我找不到任何指定这甚至可能的东西.

func SaySomething(i string = "Hello")(string){
...
}
Run Code Online (Sandbox Code Playgroud)

小智 81

不,但还有一些其他选项可以实现默认值.关于这个主题有一些很好的博客文章,但这里有一些具体的例子.


选项1:调用者选择使用默认值

// Both parameters are optional, use empty string for default value
func Concat1(a string, b int) string {
  if a == "" {
    a = "default-a"
  }
  if b == 0 {
    b = 5
  }

  return fmt.Sprintf("%s%d", a, b)
}
Run Code Online (Sandbox Code Playgroud)


选项2:最后一个可选参数

// a is required, b is optional.
// Only the first value in b_optional will be used.
func Concat2(a string, b_optional ...int) string {
  b := 5
  if len(b_optional) > 0 {
    b = b_optional[0]
  }

  return fmt.Sprintf("%s%d", a, b)
}
Run Code Online (Sandbox Code Playgroud)


选项3:配置结构

// A declarative default value syntax
// Empty values will be replaced with defaults
type Parameters struct {
  A string `default:"default-a"` // this only works with strings
  B string // default is 5
}

func Concat3(prm Parameters) string {
  typ := reflect.TypeOf(prm)

  if prm.A == "" {
    f, _ := typ.FieldByName("A")
    prm.A = f.Tag.Get("default")
  }

  if prm.B == 0 {
    prm.B = 5
  }

  return fmt.Sprintf("%s%d", prm.A, prm.B)
}
Run Code Online (Sandbox Code Playgroud)


选项4:完全可变参数解析(javascript样式)

func Concat4(args ...interface{}) string {
  a := "default-a"
  b := 5

  for _, arg := range args {
    switch t := arg.(type) {
      case string:
        a = t
      case int:
        b = t
      default:
        panic("Unknown argument")
    }
  }

  return fmt.Sprintf("%s%d", a, b)
}
Run Code Online (Sandbox Code Playgroud)

  • 太痛苦了.我希望它是:`func Concat1(一个字符串='foo',b int = 10)字符串{`就像大多数其他现代语言一样......它会将任何给定的例子减少到一行代码. (46认同)
  • @ProgramCpp不,golang不允许函数重载[Go语言有函数/方法重载吗?](/sf/ask/489086111/超载) (4认同)
  • 默认值是很棘手的,当你有一个省略该值的调用者时 - 你永远不知道他们想要的值是“实现时的默认值”还是“将来任何时候的默认值” - 这使得代码意图不那么明显。让它变得痛苦可能并没有你想象的那么糟糕。 (4认同)
  • 我们是否可以选择编写两个不同的函数并让调用者明确他们的期望。 (3认同)

sda*_*zig 47

不,谷歌的权力选择不支持.

https://groups.google.com/forum/#!topic/golang-nuts/-5MCaivW0qQ

  • [此讨论与官方声明](https://groups.google.com/forum/#!msg/golang-nuts/3Go3gPNIPaw/Pv2B5udjDgMJ)和[此相关问题](http://stackoverflow.com/questions/ 2032149 /可选参数). (4认同)

Dav*_*ave 6

不,没有办法指定默认值。我相信这样做的目的是为了提高可读性,但要花更多的时间(并且希望是在作者端)花些时间。

我认为拥有“默认”的正确方法是拥有一个新功能,该功能将默认提供给更通用的功能。有了这个,您的代码就变得更加清晰了。例如:

func SaySomething(say string) {
    // All the complicated bits involved in saying something
}

func SayHello() {
    SaySomething("Hello")
}
Run Code Online (Sandbox Code Playgroud)

花费很少的精力,我做了一个做普通事情的函数并重用了通用函数。您可以在许多库中看到这一点,fmt.Println例如,只需在其他情况下添加换行符即可fmt.Print。但是,在阅读某人的代码时,很明显他们通过调用的函数打算做什么。使用默认值时,如果不使用函数来引用默认值的实际含义,我将不知道会发生什么。

  • “仅添加另一个函数”参数会导致处理多个排列所需的方法激增,需要负担为这些方法确定有意义,可发现且易于记住的名称的负担,并增加学习使用更多方法的软件包的负担。方法与更少。#jmtcw (4认同)
  • 好吧,作为一个在 10 到 20 年后不得不整理大量源代码来查找 bug 来支持客户的人,我认为额外的函数名称可能会有一些好处 (2认同)
  • “这种方法可能有一些好处”和“让我们设计语言,使这种方法成为唯一可能的方法(即使它没有意义)”之间存在差距。 (2认同)