在Golang函数中使用默认值

I'm trying to implement a default value according to the option 1 of the post Golang and default values. But when I try to do go install the following error pops up in the terminal:

not enough arguments in call to test.Concat1
    have ()
    want (string)

Code:

package test

func Concat1(a string) string {
  if a == "" {
    a = "default-a"
  }
  return fmt.Sprintf("%s", a)
}

// other package

package main

func main() {
  test.Concat1()
}

Thanks in advance.

I don't think what you are trying to do will work that way. You may want to opt for option #4 from the page you cited, which uses variadic variables. In your case looks to me like you want just a string, so it'd be something like this:

func Concat1(a ...string) string {
  if len(a) == 0 {
    return "a-default"
  }
  return a[0]
}

Default parameters work differently in Go than they do in other languages. In a function there can be one ellipsis, always at the end, which will keep a slice of values of the same type so in your case this would be:

func Concat1(a ...string) string {

but that means that the caller may pass in any number of arguments >= 0. Also you need to check that the arguments in the slice are not empty and then assign them yourself. This means they do not get assigned a default value through any kind of special syntax in Go. This is not possible but you can do

if a[0] == "" {
    a[0] = "default value"
}

If you want to make sure that the user passes either zero or one strings, just create two functions in your API, e.g.

func Concat(a string) string { // ...

func ConcatDefault() string {
    Concat("default value")
}

Go does not have optional defaults for function arguments.

You may emulate them to some extent by having a special type to contain the set of parameters for a function.

In your toy example that would be something like

type Concat1Args struct {
  a string
}

func Concat1(args Concat1Args) string {
  if args.a == "" {
    args.a = "default-a"
  }
  return fmt.Sprintf("%s", args.a)
}

The "trick" here is that in Go each type has its respective "zero value", and when producing a value of a composite type using the so-called literal, it's possible to initialize only some of the type's fields, so in our example that would be

s := Concat1(Concat1Args{})

vs

s := Concat1(Concat1Args{"whatever"})

I know that looks clumsy, and I have showed this mostly for demonstration purpose. In real production code, where a function might have a dozen of parameters or more, having them packed in a dedicate composite type is usually the only sensible way to go but for a case like yours it's better to just explicitly pass "" to the function.