当前位置: 首页 > 面试题库 >

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

杜联
2023-03-14
问题内容

我在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
}

看到Button没有名称的指针作为函数参数使我有些困惑,这使得无法从函数内部进行引用。
但是,考虑到编译器没有抱怨,这在语法上似乎是正确的。
Go中未修饰的函数参数的目的是什么?


问题答案:

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

ParameterDecl  = [ IdentifierList ] [ "..." ] Type .

如您所见,IdentifierList(一个或多个标识符名称)放在方括号中,这意味着它是 可选的 。仅Type需要。

这样做的原因是因为名称对于调用方法或函数的人并不是很重要。重要的是参数的类型及其顺序。

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

当您不命名时,是因为您不想引用它。

因此,问题应该是: 为什么我不想引用参数?

例如,因为参数 “在那儿” (已传递),但是您不需要它,所以您不想使用它。如果我不需要它,为什么会在那里?

因为某人或某物 要求 存在特定参数。例如,您想要实现一个接口,或者您想要传递一个函数值,该函数值的签名由所需的函数类型定义。

让我们来看一个例子。我们有以下MyWriter界面:

type MyWriter interface {
    Write(p []byte) error
}

一种简化的方法io.Writer,仅返回错误,但不报告写入的字节数。如果您想提供一个仅丢弃数据的实现(类似于ioutil.Discard),那么该实现将不使用(不需要使用)其参数:

type DiscardWriter struct{}

func (DiscardWriter) Write([]byte) error { return nil }

就是这样:我们不使用接收器,我们不使用参数。两者都可以不命名。实现完全按照其应有的方式工作。

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

另一个原因可能是提供 前向
兼容性。如果发布了一个库,则在不破坏向后兼容性的情况下就不能更改或扩展参数列表(并且在Go中没有函数重载:如果您想要2个具有不同参数的变量,它们的名称也必须不同)。因此,您可以及早声明带有附加参数的导出函数或方法,但是由于您尚未使用它们,因此可以不对其命名。
这里要注意的一件事是,您不能混合命名和未命名的参数。如果您命名,则必须全部命名。如果您不需要全部,则可以使用空白标识符,如本例所示:

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

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

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



 类似资料:
  • 我想执行一个简单的本机查询,但它不起作用: 为什么我会得到这个例外?

  • 问题内容: 我想执行一个简单的本机查询,但是它不起作用: 为什么会出现此异常? 问题答案: JPA在本机查询中不支持命名参数,仅对于JPQL。您必须使用位置参数。 命名参数遵循第4.4.1节中定义的标识符规则。命名参数的使用适用于Java Persistence查询语言,而不是为本机查询定义的。 仅位置参数绑定可用于本机查询。 所以用这个 尽管JPA规范在本机查询中不支持命名参数,但某些JPA实现

  • 我在JPA 2.0中发现了非常奇怪的行为 我正在尝试构建一个看起来像这样的查询,其中 employeId 和 empDepartment 是通过 java 参数传递的长值。 但是上面的查询第一次不工作,它产生了上面的错误,但是当我第二次再次触发相同的方法时,一切都很顺利,每次都是这样,这是什么原因呢?

  • 我使用PostgreSQL和hibernate 我有这个功能: 运行我的项目后 我有这个错误: 当我运行这个查询时: 从decision中选择max(null(split_part(num_ordre_decision),“/”,3),”::int) 在数据库中我有正确的结果 例如,与数据库中的此类数据相关: 我有 1001 但我的问题和冬眠有关

  • 问题内容: 我想执行一个简单的本机查询,但是不起作用: 为什么会出现此异常? 问题答案: JPA在本机查询中不支持命名参数,仅对于JPQL。您必须使用位置参数。 命名参数遵循第4.4.1节中定义的标识符规则。命名参数的使用适用于Java Persistence查询语言,而不是为本机查询定义的。 仅位置参数绑定可用于本机查询。 所以用这个 尽管JPA规范在本机查询中不支持命名参数,但某些JPA实现(