Go语言实战-打包和工具链

所有的Go语言都会被组织成若干组文件,每组文件被称为一个包。同一个目录下的所有.go 文件必须声明同一个包名。

包命名的惯例

给包命名的惯例就是使用包所在目录的名字。这会让用户在导入包的时候,就可以清晰地知道包名。给包及其目录命名时,应该使用简洁、清晰且全小写的名字,这有利于开发时频繁输入包名。

当包名不为目录名:

工程目录如下:
.
├── config.json
├── main.go
└── usb
├── doc.go
└── driver.go
// 其中usb目录下的go文件,包名设置为usb_1。
// 在main.go中使用driver下的函数,代码如下所示:
import (
"github.com/demo/usb"
)

func main() {
// 这样调用,包名和导入的目录名不一致,会导致代码不清晰。
usb_1.Retrieve()
}

main 包

当一个包的名字为main时,那么一定会发现名为main()的函数。Go语言会试图把命名为main的包编译为二进制可执行文件。

Go 文档中常使用命令(command)这个词来指代可执行程序。作为对比,包常用来指语义上可导入的单元功能。

导入包

导入包需要关键字import。如果导入多个包,则将import语句包装到一个导入块中。

import (
"os"
"fmt"
)

标准库中的包会在Go的安装位置(GOROOT)找到,Go开发者创建的包会在GOPATH路径下找到。

GOROOT=/usr/local/Cellar/go/1.11.2/libexec
GOPATH=/Users/mike/go

远程导入

目前的大势所趋是,使用分布式版本控制系统(Distributed Version Control Systems,DVCS)来分享代码,如Github、Launchpad还有Bitbucket。Go工具链本身支持从这些网站上及类似网站获取源代码。

// 如果要 import "github.com/spf13/viper"
// 使用如下命令
// 这个命令会扫描某个包的源码树,获取能找到的所有依赖包
go get "github.com/spf13/viper"

命名导入

如果导入两个以上相同名字的包,如fmt和mylib/fmt,这种情况下,重名的包可以通过命名导入来导入。

package main

import (
"fmt"
myfmt "mylib/fmt"
)

func main() {
fmt.Println("标准库fmt")
myfmt.Println("自定义fmt")
}

函数init

所有被编译器发现的init 函数都会在 main 函数之前执行。一般是为了要在程序运行前优先完成引导工作。

// 这段示例代码包含在 PostgreSQL 数据库的驱动里
// 如果程序导入了这个包,就会调用 init 函数
// 促使 PostgreSQL 的驱动最终注册到 Go 的 sql 包里,成为一个可用的驱动。
package postgres

import (
"database/sql"
)

func init() {
sql.Register("postgres", new(PostgresDriver))
}
package main0203 import (04 "database/sql"0506 _ "github.com/goinaction/code/chapter3/dbdriver/postgres"07 )0809 func main() {10 sql.Open("postgres", "mydb")11 } 
// 使用空白标识符重命名这个导入可以让 init 函数发现并被调度运行
// 这样就可以调用 sql.Open 方法来使用 PostgreSQL 驱动
package main

import (
"database/sql"

_ "github.com/goinaction/code/chapter3/dbdriver/postgres"
)

func main() {
sql.Open("postgres", "mydb")
}

使用Go的工具

go build - 编译
go clean - 清除编译后的可执行文件
go run - 编译运行
go vet ./... - 检查代码常见错误
go fmt ./... - 格式化代码
go doc - 查阅xx包的相关文档
godoc -http=:6060 - 浏览器 http://localhost:6060 查看相关文档

与其他Go开发者合作

  1. 包应该在代码库的根目录,包名应该就是代码库的名字
  2. 包可以非常小
  3. 对代码执行go fmt
  4. 给代码写文档

依赖管理

官方推荐的Dep管理包依赖(支持Go1.9及以上版本)

MacOS

$ brew install dep

go get -u github.com/golang/dep/cmd/dep

这样就有dep命令可以使用了,最常用的就两条命令:dep init和dep ensure。

  1. 对于新项目,执行dep init命令生成dep配置文件(Gopkg.lock Gopkg.toml )和 vendor目录。提交代码时,也会把Gopkg.*和vendor目录提交。
  2. 在开发过程中,若增改了依赖,一条dep ensure就可以搞定。

小结

  • 在Go语言中包是组织代码的基本单位。
  • 环境变量 GOPATH 决定了 Go 源代码在磁盘上被保存、编译和安装的位置。
  • 开发人员可以使用 go get 来获取别人的包并将其安装到自己的 GOPATH 指定的目录
  • 想要为别人创建包很简单,只要把源代码放到公用代码库,并遵守一些简单规则就可以了。
  • Go 语言在设计时将分享代码作为语言的核心特性和驱动力。
  • 推荐使用dep管理工具来管理依赖。