dqys98341 2016-12-03 18:06
浏览 72
已采纳

在Go中,未命名的参数是否有用?

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?

  • 写回答

1条回答 默认 最新

  • douchuitang0642 2016-12-03 18:19
    关注

    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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 C++ 句柄后台鼠标拖动如何实现
  • ¥15 有人会SIRIUS 5.8.0这个软件吗
  • ¥30 comsol仿真等离激元
  • ¥15 静电纺丝煅烧后如何得到柔性纤维
  • ¥15 (标签-react native|关键词-镜像源)
  • ¥100 照片生成3D人脸视频
  • ¥15 伪装视频时长问题修改MP4的时长问题,
  • ¥15 JETSON NANO
  • ¥15 VS开发qt时如何在paintgl函数中用pushbutton控制切换纹理
  • ¥20 关于 openpyxl 处理excel文件地问题