日期:2014年7月30日
包时函数和数据的集合。使用package关键字定义一个包,文件名不需要与包名一致,包名约定使用小写字符,Go包可以由多个文件组成,但是需要使用相同的package<name>,包中方法的调用方式:<packag>.Fuction()
现在 新建一个文件even.go,even.go的文件内容如下:
package even //判断是否是偶数 func Even(i int) bool { return i % 2 == 0 } //判断是否是奇数 func odd(i int) bool { return i % 2 == 1 }
里面定义了两个函数,一个是Even,一个是odd,Even首字母大写,odd首字母小写,Even函数可以在包外访问,而odd函数不可以,这是 Go语言的约定——公有函数的名字以大写字母开头,私有函数的名字以小写字母开头。这种规则同样适用于定义在包中的新类型、全局变量等,而且"大写"的含义并不仅限于US ASCII,它被扩展到了所有的大小写字母表(拉丁文、希腊文、斯拉夫 文、亚美尼亚文和埃及古文)。
构建even包:
//打印GOPATH路径,注意GOPATH路径时在GO语言环境安装的时候设定的
$ echo $GOPATH
E:\ProgramFiles\Go\Go\GoImportPkg
//在GOPATH下面新建文件夹/src/even
$ mkdir $GOPATH/src/even
//把even.go文件拷贝到新建的目录下面
$ cp even.go $GOPATH/src/even
//跳转到新建的目录
cd $GOPATH/src/even
//打印当前目录信息
$ pwd
/e/ProgramFiles/Go/Go/GoImportPkg/src/even
//编译even.go
go bulid
//安装even包
go install
执行上述步骤之后,到$GOPATH/pkg目录下可以找到一个文件even.a,用Sublime打开查看:
213c 6172 6368 3e0a 5f5f 2e53 594d 4445
4620 2020 2020 2020 3020 2020 2020 2020
2020 2020 3020 2020 2020 3020 2020 2020
3634 3420 2020 2020 3133 3620 2020 2020
2020 600a 54e0 0100 0022 222e 4576 656e
0044 e001 0000 676f 2e73 7472 696e 672e
2266 756e 6328 696e 7429 2062 6f6f 6c22
0044 e001 0000 7479 7065 2e66 756e 6328
......
使用even包:
package main import ( "even" //导入我们刚才自定义的even包 "fmt" //GO内置包 ) func main() { i := 5 fmt.Printf("Is %d even? %v\n", i, even.Even(i)) //打印 Is 5 even? false //fmt.Printf("Is %d even? %v\n", i, even.odd(i)) //报错 提示 cannot refer to unexported name even.odd }
Go在导入包的时候,可以通过import <othername> packagenaem方式来覆盖原始的包名,且覆盖之后只能使用新的名称来调用包中的函数。
每个包都应该有包注释,在 package 前的一个注释块。对于多文件包,包注释只需要 出现在一个文件前,任意一个文件都可以。包注释应当对包进行介绍,并提供相关于包的整体信息。这会出现在 go doc 生成的关于包的页面上,并且相关的细节会一并显示。在包中每个定义(并且导出)的函数应当有一小段文字描述该函数的行为。
在Go中为包编写单元测试应当是一种习惯。编写测试需要包含 testing 包和程序 go test。
测试文件也在包目录中,被命名为*_test.go,这些测试文件和其它的Go文件都是一样的,但是go test只会执行测试函数,每个测试函数都有相同的标识,名字均以Test开头,定义方式为:func TestXxx(t *testing.T)。编写测试时,需要告诉 go test 测试是失败还是成功。测试成功则直接返回。当测试失败可以用Fail()、FailNow、Log、Fatal等函数标记 。
示例:
新建一个even_test.go文件(Go中单元测试文件的名称都约定为XXX_test.go),该文件与上述even.go文件在相同的目录下,内容如下:
package even import "testing" func TestEven(t *testing.T) { if !Even(2) { t.Log("2 should be even!") t.Fail() } }
使用了package even定义包,测试使用与被测试的包使用相同的名字空间,这 不仅仅是为了方便,也允许了测试未导出的函数和结构(同包下的私有函数是可以直接访问的)。
导入了testing包,定义测试函数TestEven,函数体中编写了一些测试规则。
此时:执行go test
说明测试通过。
修改even_test.go文件内容,再次执行go test
package even import "testing" func TestEven(t *testing.T) { if Even(2) { //去掉了! t.Log("2 should be even!") t.Fail() } }
由此可以来验证包中函数的语法规则是否正确。