【问题标题】:A use case for importing with blank identifier in golanggolang中使用空白标识符导入的用例
【发布时间】:2015-01-14 08:39:04
【问题描述】:

Go 编程语言规范规定:“要仅为其副作用(初始化)导入包,请使用空白标识符作为显式包名称。”

例如:

import _ "foo/bar"

我很难想象这个构造的用例。 Usage of the `import` statement 的公认答案提到了一个用例,其中可以加载数据库驱动程序,而无需导入程序使用该包的任何导出函数,但它忽略了读者想象的细节。

是否有现实生活中的例子(带有代码 sn-ps 和解释)来说明这个用例?

【问题讨论】:

    标签: go


    【解决方案1】:

    这是因为 init function

    每个源文件都可以定义自己的 niladic init 函数来设置所需的任何状态。 (其实每个文件可以有多个init函数。)

    finally 的意思是 finally:init 在包中的所有变量声明都评估了它们的初始化程序之后被调用,并且只有在所有导入的包都被初始化之后才会评估它们。

    这就是“What does an underscore in front of an import statement mean in Go”中提到的go-sqlite3的工作原理。

    func init() {
        sql.Register("sqlite3", &SQLiteDriver{})
    }
    

    你在“Understanding Golang Packagese”中有另一个例子:

    在某些情况下,我们可能只需要导入一个包来调用它的init 方法,我们不需要调用包的其他方法。
    如果我们导入一个包并且程序中没有使用包标识符,Go编译器会报错
    在这种情况下,我们可以使用空白标识符(_)作为包别名,这样编译器就会忽略不使用包标识符的错误,但仍然会调用init函数。

    【讨论】:

      【解决方案2】:

      我正在编写一个调整图像大小的程序。我希望它能够识别不同格式的图像,如 JPEGPNGGIF 并将它们转换为 JPEG.

      所以除了imageimage/jpeg 包之外,我还必须导入image/pngimage/gif 来注册它们各自的解码器。

      如果我没有导入这些,缩放器将能够读取 JPEG 图像。

      package main
      
      import(
        "image"
        "image/jpeg" // I wanted to export the images as JPEG
        _ "image/png"
        _ "image/gif"
      )
      
      // ...
      

      image 包中的相关文档:

      解码任何特定的图像格式都需要事先注册解码器功能。作为初始化该格式包的副作用,注册通常是自动的,因此,要解码 PNG 图像,只需:

      import _ "image/png"
      

      【讨论】:

        【解决方案3】:

        一个用例是当你想要的只是 init function 做一些初始化(例如注册自己,这样你就不必明确地调用它们)。

        一个例子是some database drivers的注册:

        import (
            "database/sql"
            _ "github.com/ziutek/mymysql/godrv"
        )
        

        【讨论】:

          猜你喜欢
          • 2020-04-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-12
          • 1970-01-01
          • 1970-01-01
          • 2022-07-18
          相关资源
          最近更新 更多