我正在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
}
它让我有点困惑,看到指向a的指针 Button
没有名称作为函数参数,这使得无法从函数内部引用。
但是,鉴于编译器没有抱怨,它似乎在语法上是正确的。
Go中的unamed函数参数的目的是什么?
未命名的参数完全有效。该 参数声明 来自规范:
ParameterDecl = [ IdentifierList ] [ "..." ] Type .
如你所见, IdentifierList
(标识符名称或名称)在方括号中,表示它 可选的。只有 Type
是必须的。
这是因为名称对于调用方法或函数的人来说并不重要。重要的是参数的类型及其顺序。这个答案详细说明: 在Golang中获取方法参数名称
通常,您可以命名变量和参数,以便可以引用它们。
当你没有说出什么名字时,那是因为你不想引用它。
所以问题应该是: 为什么我不想参考参数?
例如因为参数 “在那儿” (它被传递),但你不需要它,你不想使用它。如果我不需要它,它为什么会在那里?
因为某人或某事 使然 具体参数在那里。例如,您希望实现一个接口,或者您希望传递一个函数值,其签名由期望的函数类型定义。
我们来看一个例子吧。我们有以下内容 MyWriter
接口:
type MyWriter interface {
Write(p []byte) error
}
简化 io.Writer
它只返回错误,但不报告写入的字节数。如果你想提供一个只丢弃数据的实现(类似于 ioutil.Discard
),然后实现不使用(不需要使用)其参数:
type DiscardWriter struct{}
func (DiscardWriter) Write([]byte) error { return nil }
这就是全部:我们不使用接收器,我们不使用参数。两者都可以是未命名的。并且实现正是它应该做的。
这样做(使用未命名的参数)也是如此 文件 该值未被使用/引用。
另一个原因可以是提供 前锋 兼容性。如果您发布了库,则无法在不破坏向后兼容性的情况下更改或扩展参数列表(在Go中没有函数重载:如果您想要2个具有不同参数的变体,它们的名称也必须不同)。因此,您可以尽早声明带有其他参数的导出函数或方法,但由于您尚未使用它们,因此可能会将它们保留为未命名。这个答案详细说明了这方面的一个例子: 为什么Go允许编译未使用的函数参数?
这里要注意的一件事是你不能混合命名和未命名的参数。如果你说出一些名字,你必须全名。如果你不需要所有,你可以使用 空白标识符 像在这个例子中:
一个简单的Web服务器响应 "Hello"
所有请求的文本:
http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
io.WriteString(w, "Hello")
})
panic(http.ListenAndServe(":8080", nil))
处理程序函数发回 "Hello"
文本仅使用响应编写器 w
,但不是请求结构,因此空白标识符用作其名称。
另一个相关问题:
为什么在向Golang中的结构添加方法时必须声明变量名?
也有些相关,但关于使用/命名返回值:
在普通函数中返回Golang中的'ok'映射
关于获取方法/函数参数名称:
在Golang中获取方法参数名称