任何包系统设计的目的都是为了简化大型程序的设计和维护工做,经过将一组相关的特性放进一个独立的单元以便于理解和更新,在每一个单元更新的同时保持和程序中其它单元的相对独立性。这种模块化的特性容许每一个包能够被其它的不一样项目共享和重用,在项目范围内、甚至全球范围统一的分发和复用。html
每一个包通常都定义了一个不一样的名字空间用于它内部的每一个标识符的访问。每一个名字空间关联到一个特定的包,让咱们给类型、函数等选择简短明了的名字,这样能够在使用它们的时候减小和其它部分名字的冲突。python
每一个包还经过控制包内名字的可见性和是否导出来实现封装特性。经过限制包成员的可见性并隐藏包API的具体实现,将容许包的维护者在不影响外部包用户的前提下调整包的内部实现。经过限制包内变量的可见性,还能够强制用户经过某些特定函数来访问和更新内部变量,这样能够保证内部变量的一致性和并发时的互斥约束。mysql
每一个包是由一个全局惟一的字符串所标识的导入路径定位。出如今import语句中的导入路径也是字符串。git
import ( "fmt" "math/rand" "encoding/json" "golang.org/x/net/html" "github.com/go-sql-driver/mysql" )
在每一个Go语言源文件的开头都必须有包声明语句。包声明语句的主要目的是肯定当前包被其它包导入时默认的标识符(也称为包名)。github
一般来讲,默认的包名就是包导入路径名的最后一段,所以即便两个包的导入路径不一样,它们依然可能有一个相同的包名。例如,math/rand
包和golang.org/x/exp/rand
包的包名都是rand
。golang
package main import ( "fmt" "math/rand" ) // 导入rand包 用rand包里的方法函数等 func main() { fmt.Println(rand.Int63n(10000)) // 9410 }
package main import ( "fmt" "golang.org/x/exp/rand" ) func main() { fmt.Println(rand.Int63n(10000)) // 9351 }
若是咱们想同时导入两个有着名字相同的包,例如math/rand
包和golang.org/x/exp/rand
包,那么导入声明必须至少为一个同名包指定一个新的包名以免冲突。这叫作导入包的重命名。sql
package main import ( "fmt" rand1 "math/rand" rand2 "golang.org/x/exp/rand" ) func main() { fmt.Println(rand1.Int63n(10000)) // 9401 fmt.Println(rand2.Int63n(10000)) // 9351 }
若是只是导入一个包而并不使用导入的包将会致使一个编译错误。可是有时候咱们只是想利用导入包而产生的反作用:它会计算包级变量的初始化表达式和执行导入包的init初始化函数。这时候咱们须要抑制“unused import”编译错误,咱们能够用下划线_
来重命名导入的包。好比序号gorm
包是要带入sql驱动json
import ( "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) func main() { db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local") defer db.Close() }
当建立一个包,通常要用短小的包名,但也不能过短致使难以理解。标准库中最经常使用的包有bufio
、bytes
、flag
、fmt
、http
、io
、json
、os
、sort
、sync
和time
等包。session
包名通常采用单数的形式。标准库的bytes、errors和strings使用了复数形式,这是为了不和预约义的类型冲突,一样还有go/types是为了不和type关键字冲突。并发
Go语言工具箱的具体功能,包括如何下载、格式化、构建、测试和安装Go语言编写的程序。
$ go ... build compile packages and dependencies clean remove object files doc show documentation for package or symbol env print Go environment information fmt run gofmt on package sources get download and install packages and dependencies install compile and install packages and dependencies list list packages run compile and run Go program test test packages version print Go version vet run go tool vet on packages Use "go help [command]" for more information about a command. ...
使用Go语言工具箱的go命令,不只能够根据包导入路径找到本地工做区的包,甚至能够从互联网上找到和更新包。
使用命令go get
能够下载一个单一的包或者用...
下载整个子目录里面的每一个包。Go语言工具箱的go命令同时计算并下载所依赖的每一个包,这也是前一个例子中golang.org/x/net/html
自动出如今本地工做区目录的缘由。
go build
命令编译命令行参数指定的每一个包。若是包是一个库,则忽略输出结果;这能够用于检测包是能够正确编译的。若是包的名字是main,go build
将调用连接器在当前目录建立一个可执行程序;以导入路径的最后一段做为可执行程序的名字。
Go语言的编码风格鼓励为每一个包提供良好的文档。包中每一个导出的成员和包声明前都应该包含目的和用法说明的注释。
Go语言中的文档注释通常是完整的句子,第一行一般是摘要说明,以被注释者的名字开头。注释中函数的参数或其它的标识符并不须要额外的引号或其它标记注明。例如,下面是fmt.Fprintf的文档注释。
// 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 package time // import "time" Package time provides functionality for measuring and displaying time. const Nanosecond Duration = 1 ... func After(d Duration) <-chan Time func Sleep(d Duration) func Since(t Time) Duration func Now() Time type Duration int64 type Time struct { ... } ...many more...
或者是某个具体的包成员:
$ go doc time.Since func Since(t Time) Duration Since returns the time elapsed since t. It is shorthand for time.Now().Sub(t).
或者是一个方法:
$ go doc time.Duration.Seconds func (d Duration) Seconds() float64 Seconds returns the duration as a floating-point number of seconds.
在Go语言程序中,包是最重要的封装机制。没有导出的标识符只在同一个包内部能够访问,而导出的标识符则是面向全宇宙都是可见的。
net/http net/http/internal/chunked net/http/httputil net/url
go list
命令能够查询可用包的信息。其最简单的形式,能够测试包是否在工做区并打印它的导入路径:
$ go list github.com/go-sql-driver/mysql github.com/go-sql-driver/mysql
go list
命令还能够获取每一个包完整的元信息,而不只仅只是导入路径,这些元信息能够以不一样格式提供给用户。其中-json
命令行参数表示用JSON格式打印每一个包的元信息。能够用"..."
表示匹配相关包的包的导入路径。
$ go list ...mysql github.com/astaxie/beego/session/mysql github.com/go-sql-driver/mysql
参考文章: