包和工具
包为了便于函数复用和封装;实际项目中为了快速开发会引入外部工具包;
go编译速度快捷的主要原因:
- 引入包文件头部显示声明;文件解析只要读头部即可知道依赖关系;
- 禁止循环依赖;可以独立也可以并发编译;
- 编译后目标文件记录了包导出信息和依赖关系;
导入路径
import (
"fmt"
"math/rand"
"encoding/json"
"golang.org/x/net/html"
"github.com/go-sql-driver/mysql"
)
每个包是由一个全局唯一的字符串所标识的导入路径定位。
包声明(包名)
文件的开头必须有包声明语句,主要用于确定当前包被其他包导入时默认的标识符;
package main
import (
"fmt"
"math/rand"
)
func main() {
fmt.Println(rand.Int())
}
这个文件里package main即是包声明,,main包中通过math/rand包声明导入该包,这样你就可以通过rand.Int()调用该包中方法;
默认包名是包导入路径名的最后一段;
例外情况:
- 引入main包时,导入路径无关紧要
- 测试文件_test.go
- 依赖版本号管理工具会追加版本号信息.如:liu/niu.v2,包名应该是niu
导入包时可以进行重命名,它可以区分同名包以及简化导入包名;
import (
"crypto/rand"
mrand "math/rand" // alternative name mrand avoids conflict
stupid "go/zzlhisastupidcompany"
)
包匿名导入
golang中如果导入包但是不使用会造成编译错误.但是有时候我们就想这么用,因为公共方法的抽取很多时候我们不会直接使用具体的类,如果不引用具体的包
会造成具体方法初始化失败.因此我们通过匿名导入的方式来引入包,便于具体类执行时进行包级别变量初始化表达式和执行包的初始化函数,并抑制"unused import"编译错误.
格式:
import _ "image/png" // 通过下划线 _ 来重命名导入包,它是空白标识符,不能被访问.
包命名
- 名称短小且易于理解.如:bufio,http,fmt
- 有描述性且无歧义.imageutil和ioutilis已经够简洁,不需要命名为util了;避免包名和局部变量冲突,所以包名和局部变量要做好约定,如path包引入;
- 包名一般采用单数.bytes,errors,strings是为了避免和关键字冲突才这样命名
- 避免歧义.如温度转换包命名为temp,后续可能会纠结temp是温度还是临时变量.但是使用temperature又不直观,使用tempconv更好一些.
- 包成员命名.包名和成员名要有层次,简洁直观.如:bytes.Equal,flag.Int,http.Get,json.Marshal等
工具
go便于项目管理提供了一系列功能的命令集.包含了包下载,格式化,构建,测试和安装等;
-
下载包
go get可以下载指定包或下载整个子目录里的每个包(...);-u参数用于下载所有最新版本;
检查包格式:$GOPATH/bin/golint gopl.io/ch2/popcount -
构建包
go build:编译命令行参数指定的每个包.只编译修改过的包;-i参数用于安装每个目标所依赖的包
go install:保存编译结果;被编译的包将保存到$GOPATH/pkg目录下,目录路径和src目录路径对应,可执行程序被保存到$GOPATH/bin; -
包文档
包中导出的成员和包声明前应该包含目的和用法说明的注释;第一行是摘要,以注释者的名字开头;注释中函数的参数或其他标识符不需要引号或其他标记注明;
// Fprintf formats according to a format specifier and writes to w. // It returns the number of bytes written and any write error encountered. func Fprintf(w io.Writer, format string, a ...interface{}) (int, error)
- go doc.不需要完整的包导入路径或正确的大小写
go doc time:查看time文档注释
go doc time.Since:查看time的成员注释- godoc.在线服务https://godoc.org
-
内部包
包通过大小写区分外部是否可以访问,但是很多时候需要一些可信赖的外部包访问指定包,这时就是用内部包;go会对包含internal名字的路径段的包导入进行特殊处理,internal包只能被和internal目录有同一个父目录的包所引用.
chunked包可以被net/http/httputil和net/http包引用,但是不能被net/url引用;net/url包可以引用net/http/httputil(它不是内部包)net/http
net/http/internal/chunked
net/http/httputil
net/url -
查询包
go list:查询可用包信息.它还可以进行模糊查询,通过一些参数进行结果格式化
go list github.com/go-sql-driver/mysql:查询mysql包信息
go list ...:查询工作区所有包信息