Go中的未命名参数是什么?

aur*_*enC 15 arguments go

我正在Go for Go中编写一个解析器,为了测试它,我从github项目中下载了一堆文件.
https://github.com/andlabs/ui中,我碰到了包含这段代码的文件:

func moveLabel(*Button) {
    from := movingCurrent
    to := 0
    if from == 0 {
        to = 1
    }
    movingBoxes[from].Delete(0)
    movingBoxes[to].Append(movingLabel, false)
    movingCurrent = to
}
Run Code Online (Sandbox Code Playgroud)

有点让我感到困惑的是看到一个Button没有名字的指针作为函数参数,这使得无法从函数内部引用.
但是,鉴于编译器没有抱怨,它似乎在语法上是正确的.
Go中的unamed函数参数的目的是什么?

icz*_*cza 21

未命名的参数完全有效.规范中的参数声明:

ParameterDecl  = [ IdentifierList ] [ "..." ] Type .
Run Code Online (Sandbox Code Playgroud)

如您所见,IdentifierList(标识符名称或名称)位于方括号中,这意味着它是可选的.只Type需要.

这是因为名称对于调用方法或函数的人来说并不重要.重要的是参数的类型及其顺序.这个答案详细说明:在Golang中获取方法参数名称

通常,您可以命名变量和参数,以便可以引用它们.

如果你没有命名,那是因为你不想引用它.

所以问题应该是:为什么我不想引用参数?

例如,因为参数"在那里"(它被传递),但你不需要它,你不想使用它.如果我不需要它,它为什么会在那里?

因为某人或某事要求特定参数存在.例如,您希望实现一个接口,或者您希望传递一个函数值,其签名由期望的函数类型定义.

我们来看一个例子吧.我们有以下MyWriter界面:

type MyWriter interface {
    Write(p []byte) error
}
Run Code Online (Sandbox Code Playgroud)

简化版io.Writer仅返回错误,但不报告写入的字节数.如果你想提供一个只丢弃数据的实现(类似于ioutil.Discard),那么实现不会使用(不需要使用)它的参数:

type DiscardWriter struct{}

func (DiscardWriter) Write([]byte) error { return nil }
Run Code Online (Sandbox Code Playgroud)

这就是全部:我们不使用接收器,我们不使用参数.两者都可以是未命名的.并且实现完全符合它的要求.

这样做(使用未命名的参数)也会记录该值未被使用/引用.

另一个原因可能是提供向前兼容性.如果您发布了库,则无法在不破坏向后兼容性的情况下更改或扩展参数列表(并且在Go中没有函数重载:如果您想要2个具有不同参数的变体,它们的名称也必须不同).因此,您可以尽早声明带有其他参数的导出函数或方法,但由于您尚未使用它们,因此可能会将它们保留为未命名.此答案中详细说明了这一点:为什么Go允许编译未使用的函数参数?

这里要注意的一件事是你不能混合命名和未命名的参数.如果你说出一些名字,你必须给所有人命名.如果您不需要全部,则可以使用此示例中的空白标识符:

一个简单的Web服务器,它响应"Hello"所有请求的文本:

http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
    io.WriteString(w, "Hello")
})
panic(http.ListenAndServe(":8080", nil))
Run Code Online (Sandbox Code Playgroud)

发送回"Hello"文本的处理函数仅使用响应编写器w,而不使用请求结构,因此空白标识符用作其名称.

另一个相关问题:

为什么在向Golang中的结构添加方法时必须声明变量名?

也有些相关,但关于使用/命名返回值:

在普通函数中返回Golang中的'ok'映射

关于获取方法/函数参数名称:

在Golang中获取方法参数名称

  • @Jun 接口中的参数名称除了文档和提高易读性之外没有真正的目的。实现该接口的人可能会使用不同的名称或省略其名称,但这并不重要。即使姓名不同,签名也匹配。 (2认同)

Ami*_*aei 10

未命名的参数有效但不可引用。

它们只是为了满足接口和签名。