【问题标题】:Meaning of underscore (blank identifier) in Go [duplicate]Go中下划线(空白标识符)的含义
【发布时间】:2014-08-12 23:14:11
【问题描述】:

当我阅读 Go 文档时,我发现了这个:

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

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

我不明白 _ 的用途,我在其他作业中看到过它,但不明白它的含义。深入挖掘我发现它被称为“空白标识符”,但我不明白他们提出的用例:

_ = x // evaluate x but ignore it

围棋成语对我来说仍然有点陌生,所以我试图理解我为什么要做这样的事情。

【问题讨论】:

标签: go


【解决方案1】:

“计算机科学中只有两件难事:缓存失效和命名”。蒂姆·布雷(Tim Bray)引用菲尔·卡尔顿(Phil Karlton)

这是关于不必命名的事情。

在 Go 中,当您不想使用 afoo 作为示例变量名时,可以使用 _。而已!他们本可以写var a I = T{},结果会是一样的(除了未使用的变量在 Go 中是一个错误)。

有关空白标识符的其他用途,请阅读Effective Go

【讨论】:

    【解决方案2】:

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

    例如,在 Go 中,返回错误是很常见的。如果由于某种原因您不关心该错误,则可以选择忽略它:

    value, _ := methodThatReturnsValueAndError()
    

    但是,如果您分配它而不使用它,则会出现编译器错误:

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

    【讨论】:

      【解决方案3】:

      _ 是一个特殊的标识符,你可以分配任何东西,但从不读取。在您给出的第一个示例中:

      var _ I = T{}
      

      无法访问此变量,因此它将在生成的程序之外进行优化。但是,如果类型T 不能分配给接口I,则可能会导致编译错误。所以在这种情况下,它被用作关于类型的静态断言。

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

      a, _ = foo()
      

      您可以通过创建另一个变量来保存不需要的返回值来获得相同的效果,但此功能意味着您无需担心为其选择唯一名称。

      【讨论】:

      • AFAIK,您上一条语句中的问题不仅在于为不需要的变量选择唯一名称,而且在选择名称后您还需要使用它。否则go编译器会抛出“变量未使用”之类的错误。
      • @Suhas,这是真的。
      【解决方案4】:

      简单来说 _ 是一个被忽略的值。 Go 不允许未使用的局部变量,如果您尝试这样做,则会引发编译错误。所以你通过放置一个 _

      来欺骗编译器说“请忽略这个值”

      例如:

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

      Here Go 引发编译错误,因为您在循环中根本没有使用 index (未使用的局部变量)。现在你应该对 _ 进行索引,让编译器忽略它。

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

      【讨论】:

        【解决方案5】:

        Go 编译器几乎不允许已声明但未使用的变量。像这样,

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

        在这种情况下,给定的代码会显示一些错误 -> “已声明但未使用”。
        因此,我们使用以下 sn-p 解决它:

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


        至于 import 部分,它是关于仅通过其副作用来导入包。
        请参考这个link

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-03-01
          • 1970-01-01
          • 2023-03-10
          • 2020-01-04
          • 2012-12-25
          • 2020-04-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多