Is unnamed arguments a thing in Go?

Unnamed parameters are perfectly valid. The Parameter declaration from the spec:

ParameterDecl  = [ IdentifierList ] [ "..." ] Type .

As you can see, the IdentifierList (the identifier name or names) is in square brackets, which means it’s optional. Only the Type is required.

The reason for this is because the names are not really important for someone calling a method or a function. What matters is the types of the parameters and their order. This is detailed in this answer: Getting method parameter names in Golang

Generally you name variables and parameters so that you can refer to them.

When you don’t name something, it’s because you don’t want to refer to it.

So the question should rather be: Why would I not want to refer to a parameter?

For example because the parameter “is there” (it is passed), but you don’t need it, you don’t want to use it. Why would it be there if I don’t need it?

Because someone or something dictates for specific parameters to be there. For example you want to implement an interface, or you want to pass a function value whose signature is defined by the function type that is expected.

Let’s see an example. We have the following MyWriter interface:

type MyWriter interface {
    Write(p []byte) error
}

A simplified io.Writer which only returns an error, but does not report the number of bytes written. If you’d want to provide an implementation which just discards the data (similar to ioutil.Discard), then the implementation does not use (does not need to use) its argument:

type DiscardWriter struct{}

func (DiscardWriter) Write([]byte) error { return nil }

And that’s all: we don’t use the receiver, we don’t use the argument. Both can be unnamed. And the implementation does exactly what it should.

Doing so (using unnamed parameters) also documents that the value is not used / referred to.

Another reason can be to provide forward compatibility. If you release a library, you can’t change or extend the parameter list without breaking backward compatibility (and in Go there is no function overloading: if you want 2 variants with different parameters, their names must be different too). So you may declare an exported function or method with additional parameters early, but since you don’t use them yet, you may leave them unnamed. An example of this is detailed in this answer: Why does Go allow compilation of unused function parameters?

One thing to note here is that you can’t mix named and unnamed parameters. If you name some, you must name all. If you don’t need all, you may use the blank identifier like in this example:

A simple web server which responds with the "Hello" text to all requests:

http.HandleFunc("https://stackoverflow.com/", func(w http.ResponseWriter, _ *http.Request) {
    io.WriteString(w, "Hello")
})
panic(http.ListenAndServe(":8080", nil))

The handler function sending back the "Hello" text only uses the response writer w, but not the request structure, so the blank identifier is used as its name.

Another related question:

Why must we declare a variable name when adding a method to a struct in Golang?

Also somewhat related, but regarding using / naming returned values:

Return map like ‘ok’ in Golang on normal functions

And regarding getting method / function parameter names:

Getting method parameter names in Golang

Leave a Comment