I am writing a parser in Go for Go, and to test it I downloaded a bunch of files from github projects.
In https://github.com/andlabs/ui I bumped into a file containing this piece of code:
func moveLabel(*Button) {
from := movingCurrent
to := 0
if from == 0 {
to = 1
}
movingBoxes[from].Delete(0)
movingBoxes[to].Append(movingLabel, false)
movingCurrent = to
}
It confuse me a bit to see a pointer to a Button
without a name as a function argument, which makes it impossible to reference from inside the function.
However, it seems to be syntactically correct given that the compiler doesn't complains.
What is the purpose of unamed functions arguments in Go?
An anonymous function is a function which doesn't contain any name. It is useful when you want to create an inline function. In Go language, an anonymous function can form a closure. An anonymous function is also known as function literal.
Command-line arguments are a way to provide the parameters or arguments to the main function of a program. Similarly, In Go, we use this technique to pass the arguments at the run time of a program. In Golang, we have a package called as os package that contains an array called as “Args”.
In Golang, a function that can be called with a variable argument list is known as a variadic function. One can pass zero or more arguments in the variadic function. If the last parameter of a function definition is prefixed by ellipsis …, then the function can accept any number of arguments for that parameter.
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("/", 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
Unnamed parameters are valid but not referenceable.
They're just for satisfaction of interfaces and signatures.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With