在Go中导入包

利用软件包可以使我们的程序更加强大和强大。本教程将引导您完成安装,导入和别名包。

介绍

有时您的代码需要在当前程序之外的其他功能。 在这些情况下,您可以使用包来使您的程序更复杂。 包表示磁盘上单个目录中的所有文件。 包可以定义您可以在其他Go文件或包中引用的函数,类型和接口。

本教程将引导您完成安装,导入和别名包。

标准库包

Go附带的标准库是一组包。 这些软件包包含许多编写现代软件的基本构建块。 例如, fmt包包含用于格式化和打印字符串的基本功能。 net/http包含允许开发人员创建Web服务,通​​过http协议发送和检索数据等的功能。

要使用包中的函数,需要使用import语句访问包。 import语句由import关键字和包的名称组成。

例如,在Go程序文件random.go您可以导入math/rand包以这种方式生成随机数:

random.go
import "math/rand"

当我们导入一个包时,我们将它作为一个单独的命名空间在我们当前的程序中使用。 这意味着我们必须以点表示法引用函数,就像在package . function package . function

实际上, math/rand包中的函数看起来像这些例子:

  • rand.Int()调用函数返回一个随机整数。
  • rand.Intn()调用函数将一个随机元素从0返回到提供的指定数字。

让我们创建一个for循环来展示我们如何在random.go程序中调用math/rand包的random.go

random.go
package main

import "math/rand"

func main() {
  for i := 0; i < 10; i++ {
    println(rand.Intn(25))
  }
}

该程序首先在第三行导入math/rand包,然后进入for循环,该循环将运行10次。 在循环内,程序将打印025范围内的随机整数。 整数25作为参数传递给rand.Intn()

当我们使用go run random.go运行程序时,我们将收到10个随机整数作为输出。 因为这些是随机的,所以每次运行程序时,您可能会得到不同的整数。 输出看起来像这样:

6
12
22
9
6
18
0
15
6
0

整数永远不会低于0或高于24。

导入多个包时,可以使用()创建块。 通过使用块,您可以避免在每一行重复import关键字。 这将使您的代码看起来更干净:

random.go

import (
  "fmt"
  "math/rand"
)

为了利用附加包,我们现在可以格式化输出并打印出在循环期间生成每个随机数的迭代:

random.go
package main

import (
  "fmt"
  "math/rand"
)

func main() {
  for i := 0; i < 10; i++ {
    fmt.Printf("%d) %d\n", i, rand.Intn(25))
  }
}

现在,当我们运行程序时,我们将收到如下所示的输出:

0) 6
1) 12
2) 22
3) 9
4) 6
5) 18
6) 0
7) 15
8) 6
9) 0

在本节中,我们学习了如何导入包并使用它们来编写更复杂的程序。 到目前为止,我们只使用了标准库中的包。 接下来,让我们看看如何安装和使用由其他开发人员编写的包。

安装包

虽然标准库附带了许多优秀且有用的软件包,但它们有意设计为通用的,而不是特定的。 这允许开发人员根据自己的特定需求在标准库之上构建自己的包。

Go工具链随go get命令一起提供。 此命令允许您将第三方软件包安装到本地开发环境并在程序中使用它们。

当使用go get安装第三方软件包时,通常会通过其规范路径引用软件包。 该路径也可以是托管在代码存储库(如GitHub)中的公共项目的路径。 因此,如果要导入flect包,则可以使用完整的规范路径:

go get github.com/gobuffalo/flect

go get工具将在这种情况下在GitHub上找到包,并将其安装到$GOPATH

对于此示例,代码将安装在此目录中:

$GOPATH/src/github.com/gobuffalo/flect

原始作者经常更新包以解决错误或添加新功能。 发生这种情况时,您可能希望使用该软件包的最新版本来利用新功能或已解决的错误。 要更新包,可以将-u标志与go get命令一起使用:

go get -u github.com/gobuffalo/flect

如果在本地找不到该命令,则此命令也将安装Go。 如果已经安装,Go将尝试将软件包更新到最新版本。

go get命令始终检索可用包的最新版本。 但是,可能会对程序包的先前版本进行更新,这些程序仍然比您正在使用的程序更新,并且在程序中进行更新时非常有用。 要检索该特定版本的软件包,您需要使用软件包管理工具,例如Go Modules

从Go 1.11开始,Go Modules用于管理要导入的软件包的版本。 包管理的主题超出了本文的范围,但您可以在Go Modules GitHub页面上阅读更多相关内容。

别名导入的包

如果您的本地程序包的名称与您正在使用的第三方程序包相同,则可能需要更改程序包名称。 发生这种情况时,别名导入是处理冲突的最佳方法。 您可以通过在导入的包前面添加alias来修改Go中包及其功能的名称。

此语句的构造如下所示:

import another_name "package"

在此示例中,修改random.go程序文件中fmt软件包的名称。 我们将fmt的包名称更改为f以缩写它。 我们修改后的程序将如下所示:

random.go
package main

import (
 f "fmt"
  "math/rand"
)

func main() {
  for i := 0; i < 10; i++ {
    f.Printf("%d) %d\n", i, rand.Intn(25))
  }
}

在程序中,我们现在将Printf函数称为f.Printf而不是fmt.Printf

虽然其他语言喜欢使用程序包混叠,以便以后在程序中使用,但Go没有。 例如,将fmt软件包别名fmt f样式指南不一致。

重命名导入以避免名称冲突时,您应该重命名最本地或项目特定的导入。 例如,如果您有一个名为strings本地包,并且还需要导入名为strings系统包,则您更愿意通过系统包重命名本地包。 只要有可能,最好完全避免名称冲突。

在本节中,我们学习了如何为导入设置别名以避免与程序中的其他导入冲突。 重要的是要记住程序的可读性和清晰度很重要,因此您应该只使用别名来使代码更具可读性,或者何时需要避免命名冲突。

格式化导入

通过格式化导入,您可以将包排序为特定顺序,从而使代码更加一致。 此外,当唯一改变的是导入的排序顺序时,这将阻止随机提交发生。 由于格式化导入将阻止随机提交,这将防止不必要的代码流失和令人困惑的代码审查。

大多数编辑器会自动为您设置格式,或者让您将编辑器配置为使用goimports 在编辑器中使用goimports被认为是标准做法,因为尝试手动维护导入的排序顺序可能很乏味且容易出错。 此外,如果进行任何样式更改,将更新goimports以反映这些样式更改。 这可以确保您和代码中的任何人在导入块中具有一致的样式。

以下是格式化之前导入块的示例:

import (
  "fmt"
  "os"
  "github.com/digital/ocean/godo"
  "github.com/sammy/foo"
  "math/rand"
  "github.com/sammy/bar"
)

运行goimport工具(或大多数安装了它的编辑器,保存文件将为您运行),您现在将具有以下格式:

import (
  "fmt"
  "math/rand"
  "os"

  "github.com/sammy/foo"
  "github.com/sammy/bar"

  "github.com/digital/ocean/godo"
)

请注意,它首先对所有标准库包进行分组,然后将第三方包与空行分组在一起。 这使得更容易阅读和理解正在使用的包。

在本节中,我们了解到使用goimports将保持所有导入块的格式正确,并防止在处理相同文件的开发人员之间进行不必要的代码流失。

结论

当我们导入包时,我们可以调用Go内置的函数。 有些软件包是使用Go安装的标准库的一部分,有些软件包是通过go get安装的。

利用软件包,我们可以利用现有代码,使我们的程序更加强大和强大。 我们还可以为自己和其他程序员创建自己的包 ,以便在将来的程序中使用。