Naming function parameters and results

March 30, 2023

Function types

Within a list of parameters or results, the names (IdentifierList) must either all be present or all be absent. If present, each name stands for one item (parameter or result) of the specified type and all non-blank names in the signature must be unique.

There are several things to unpack here. Let’s start with the most intuitive part: The names of function parameters and results must be unique.

func(a int, a string) // Invalid: can't have two parameters with the same name
func(a int) (a int)   // Invalid: can't have a parameter and result with the same name

Working our way backwards through the paragraph, we next come to the idea of a blank parameter or result. What’s that?

Remember: parameter and result names don’t affect the function type at all. They serve merely as documentation. If you don’t feel the need to provide a name for the sake of documentation, you may omit the name by using the blank identifier:

func(a int, _ string)                  // The second argument is ignored by the function, but must be provided by the caller
func(a int) (_ int, err error)         // The first result has no name, and is not instantiated when the function is called.
func(_ int, _ string) (_ int, _ error) // You may use the blank identifier for all parameters and results

But that last example is a bit overly verbose. So the we come finally to the idea that the names may be entirely omitted. But they must all be omitted in that case. The following are all valid representations of the same function type.

func(a int, b string) (c int, e error)
func(a int, _ string) (_ int, err error)
func(_ int, _ string) (_ int, _ error)
func(int, string) (int, error)

Quotes from The Go Programming Language Specification Version of December 15, 2022

Share this

Related Content

Unparenthesized results

Function types … Parameter and result lists are always parenthesized except that if there is exactly one unnamed result it may be written as an unparenthesized type. But more directly: Function parameters must always be wrapped in parenthesis. Function reults must be wrapped in parenthesis if there is more than one result, or if the result is named. Further, though not clear from this wording in the spec, if there are no results, no parenthesis are required, even though if there are no parameters, they are still required.

Collapsing like function parameters

Yesterday we learned that we may omit function parameter and result names in a function type definition. But this poses a small limitation: Function types … If [the name is] absent, each type stands for one item of that type. What does that mean, exactly? Well, when using named parameters and results, we have the option to omit the type for subesquent arguments of the same type. Here’s an example to make it more clear;

Variadic functions

Generally speaking, Go doesn’t allow for the use of optional function parameters. But there is one exception, and that’s where variadic functions come into play. Function types The final incoming parameter in a function signature may have a type prefixed with .... A function with such a parameter is called variadic and may be invoked with zero or more arguments for that parameter. Probably the most ubiquitous example of a variadic function would be fmt.