Go中的包代表了相关联的代码的单位,在其他语言中经常称为库.
包由一个目录下的多个文件组成.这个目录和包是一对一映射的.
一个仓库中可以包含多个包.
Go的标准库就是通过一系列包来提供的.
包是用导入路径来标识的,比如github.com/gomarkdown/markdown是解析markdown格式的包的导入路径.
用go get本地安装包
你必须先把包下载到本地才能进行安装.
比如使用go get -u github.com/gomarkdown/markdown
从https://github.com/gomarkdown/markdown/ 下载代码
-u的意思是如果之前下载过则更新此包到最新的版本
代码将被下载到$GOPATH/src/github.com/gomarkdown/markdown, 因此包导入路径就是包代码在本地存储的路径.
导入路径被添加到$GOPATH/src.
多数情况下,导入路径也是源文件的位置,但是go get也允许通过嵌入HTML文件的元数据进行重定向。
导入包
可以用以下方式导入包:
import "path/to/package1"
import "path/to/package2"
或者组合在一起导入:
import (
"path/to/package1"
"path/to/package2"
)
这将在$ GOPATH中查找.go文件的相应导入路径,并允许你通过packagename.AnyExportedName访问导出的名称。
在下面的工程结构中,你还可以通过./前缀访问当前目录下的本地包
project
├── src
│ ├── package1
│ │ └── file1.go
│ └── package2
│ └── file2.go
└── main.go
可以在main.go中调用此命令,以将file1.go和file2.go导入代码中:
import (
"./src/package1"
"./src/package2"
)
由于软件包名称可能会在不同的库中发生冲突,因此你可能希望将一个软件包别名为新名称。 可以通过在导入语句前面加上要使用的名称来完成此操作:
import (
"fmt" //fmt from the standardlibrary
tfmt "some/thirdparty/fmt" //fmt from some other library
)
这使可以使用fmt.访问前一个fmt软件包,并使用tfmt.*访问后一个fmt软件包。
这是一种不好的样式,但是可以将包导入全局名称空间,以避免使用包前缀:
import (
. "fmt"
)
上面的Printf与fmt.Printf相同。
如果你导入软件包但不使用它,Go编译器将报告错误。 要解决此问题,可以将别名设置为下划线:
import (
_ "fmt"
)
如果你不直接使用软件包,但需要运行软件包的init函数的时候应该这么做。
新建包
如果你想创建一个Go包。
可以使用任何源代码托管服务。对于本教程,假设你使用的是https://github.com,你的帐户为kjk,要创建包foo。
在GitHub创建仓库foo
创建目录 $GOPATH/src/github.com/kjk 然后在这个目录checkout代码
$ mkdir -p $GOPATH/src/github.com/kjk
$ cd $GOPATH/src/github.com/kjk
$ git clone github.com/kjk/foo
创建文件main.go:
package foo
func Bar() string {
return "bar"
}
这是定义包Bar方法的最简单的包。
请注意,程序包名称foo与目录名称foo匹配。 它不是必需的,但是建议这么做。
包初始化
包可以有一个或多个初始化方法, 这些方法在main函数执行前只跑一次
package foo
func init() {
// init code
}
如果你只想运行程序包初始化而不从中引用任何内容,请使用以下导入表达式:
import _ "foo"
包初始化功能用于创建包中代码所需的初始状态。
不要在init函数中做太多事情。 这种隐式逻辑会对其他人理解代码产生负面影响。
包命名最佳实践:
最好将程序包名称与导入路径的最后一个路径元素的名称相同。
如果你的GitHub帐户为github.com/kjk,而你正在编写包markdown,则其导入路径应为github.com/kjk/markdown。
一个常见的错误是将go包含在导入路径中,例如 命名包markdown并给它导入路径github.com/kjk/go-markdown。