Meaning of underscore (blank identifier) in Go

huangapple go评论96阅读模式
英文:

Meaning of underscore (blank identifier) in Go

问题

在阅读Go文档时,我发现了这个内容:

>你可以通过尝试赋值来要求编译器检查类型T是否实现了接口I:

type T struct{}
var _ I = T{} // 验证T是否实现了I。

我不明白下划线(_)的用途,我在其他赋值语句中也见过它,但不明白它的含义。深入研究后,我发现它被称为“空白标识符”,但我不明白他们给出的用例:

_ = x // 计算x的值,但忽略它

Go的习惯用法对我来说仍然有点陌生,所以我正在努力理解为什么我会想要做这样的事情。

英文:

As I was reading the Go docs I found this:

>You can ask the compiler to check that the type T implements the interface I by attempting an assignment:

type T struct{}
var _ I = T{} // Verify that T implements I.

I don't understand what the _ is used for and I've seen it in other assignments but cannot understand what it means. Digging deeper I found that it's called "blank identifier" but I don't understand the use case they put:

_ = x // evaluate x but ignore it

Go idioms still feel a little alien to me so I'm trying to understand why I would want to do something like this.

答案1

得分: 37

_是一个特殊的标识符,你可以将任何值赋给它,但永远不会从中读取。在你给出的第一个例子中:

var _ I = T{}

无法访问这个变量,因此它将被优化掉,不会出现在最终的程序中。然而,如果类型T不能赋值给接口I,它可能会导致编译错误。所以在这种情况下,它被用作对类型的静态断言。

第二种情况更常见。虽然丢弃函数调用的结果可能看起来很奇怪,但在具有多个返回值的函数中,这样做可能更有意义。考虑一个返回两个值的函数foo,但你只对第一个值感兴趣。你可以使用_来忽略第二个值:

a, _ = foo()

你也可以通过创建另一个变量来保存不需要的返回值来实现相同的效果,但这个特性意味着你不需要担心为它选择一个唯一的名称。

英文:

_ is a special identifier you can assign anything to but never read from. In the first example you gave:

var _ I = T{}

There is no way to access this variable so it will be optimised out of the resulting program. However, it could cause a compile error if the type T is not assignable to the interface I. So in this case it is being used as a static assertion about a type.

The second case is more common. While it might seem strange to throw away the result of a function call, it can make more sense in functions with multiple returns. Consider a function foo that returns two values but you're only interested in the first? You can use _ to ignore the second:

a, _ = foo()

You could get the same effect by creating another variable to hold the unwanted return value, but this feature means you don't need to worry about picking a unique name for it.

答案2

得分: 11

这在允许多个返回值的语言中很常见。有些情况下,你实际上并不关心其中一个返回值。

例如,在Go语言中,经常返回一个错误。如果由于某种原因你不关心这个错误,你可以选择忽略它:

value, _ := methodThatReturnsValueAndError()

然而,如果你赋值了但没有使用它,会出现编译错误:

value, err := methodThatReturnsValueAndError()
// 如果你不使用 "err" .. 这是一个错误
英文:

This is common in languages that allow multiple return values. There are situations where you don't actually care about one of the return values.

For example, in Go, it is common to return an error. If for some reason you don't care about that error, you can choose to ignore it:

value, _ := methodThatReturnsValueAndError()

If however, you assign it and don't use it, there is a compiler error:

value, err := methodThatReturnsValueAndError()
// if you don't use "err" .. its an error

答案3

得分: 4

“在计算机科学中,只有两件难事:缓存失效和命名事物。”蒂姆·布雷引用菲尔·卡尔顿的话。

这是关于不必命名事物的内容。

在Go语言中,当你不想使用afoo作为示例变量名时,可以使用_。就是这样!他们本可以写成var a I = T{},结果是一样的(除了在Go语言中未使用的变量会报错)。

关于空白标识符的其他用法,请阅读《Effective Go》。

英文:

> “There are only two hard things in Computer Science: cache invalidation and naming things”. Tim Bray quoting Phil Karlton

This is about not having to name things.

In Go, when you don't want to use a or foo as an example variable name, you can use _. That's it! They could have written var a I = T{}, the result would have been the same (except that unused variables are an error in Go).

For other uses of the blank identifier, read Effective Go.

答案4

得分: 4

简单来说,下划线(_)是一个被忽略的值。Go语言不允许未使用的局部变量,并且如果你尝试这样做,会抛出编译错误。所以你可以通过使用下划线来欺骗编译器,告诉它“请忽略这个值”。

例如:

// 这里的os.Args的范围返回索引和值
for index, arg := range os.Args[1:] {
fmt.Println(arg)
}

在这个例子中,Go会抛出编译错误,因为你在循环中根本没有使用index(未使用的局部变量)。现在你可以将index改为_,告诉编译器忽略它。

for _, arg := range os.Args[1:] {
fmt.Println(arg)
}

英文:

In simple words _ is an ignored value. Go doesn't permit unused local variables and throws a compilation error if you try to do so. So you trick compiler saying "please ignore this value" by placing a _

For example:

// Here range of os.Args returns index, value
for index, arg := range os.Args[1:] {
	fmt.Println(arg)
}

Here Go throws compilation error because you are not using <b>index</b> (un used local variable) at all in the loop. Now you should make index to _ to say compiler to ignore it.

for _, arg := range os.Args[1:] {
	fmt.Println(arg)
}

答案5

得分: 3

Go编译器基本上禁止声明但未使用的变量。就像这样:

for i, myvalue := range myvar {
    total += mvalue
}

给定的代码将在这种情况下显示一个错误,即"声明但未使用"。因此,我们可以使用以下代码片段来解决:

for _, myvalue := range x {
    total += myvalue
}

至于import部分,它是关于仅通过其副作用导入一个包。请参考此链接

英文:

The Go compiler pretty much disallows variables that are declared but not used. Like so, <br/>

for i, myvalue := range myvar {
	total += mvalue
}

The given code will show an error somewhat in this context -> "declared but not used".<br/>
Hence, we solve it using the following snippet:<br/>

for _, myvalue := range x {
	total += myvalue
}

<br/>As for the import part, it's about importing a package solely by its side-effects.<br/>
Please refer on this link.

huangapple
  • 本文由 发表于 2014年6月23日 08:30:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/24357028.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定