Is unnamed arguments a thing in Go?

前端 未结 2 1791
小蘑菇
小蘑菇 2020-12-03 05:44

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 t

相关标签:
2条回答
  • 2020-12-03 06:00

    The purpose of unnamed function arguments is for arguments (which are local variables of the function) which are not referred to in the function's code, and therefore do not need a name. An interesting note about anonymous variables is that they are actually used more commonly than you may think. In Go, a function's return value(s) are usually listed as types, but actually they are also local variables of the function which can be named and manipulated.

    See this example in the "Effective Go" page on golang.org https://golang.org/doc/effective_go.html#named-results

    func ReadFull(r Reader, buf []byte) (n int, err error) {
        for len(buf) > 0 && err == nil {
            var nr int
            nr, err = r.Read(buf)
            n += nr
            buf = buf[nr:]
        }
        return
    }
    
    0 讨论(0)
  • 2020-12-03 06:21

    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

    0 讨论(0)
提交回复
热议问题