第3章-打包和工具链
3.1 包
包的设计理念:用来封装不同的语义单元的功能。好处:1、更好的复用代码。2、更好的管理包中数据的使用。
Go语言程序会被组织成若干组文件,每组文件叫做一个包。每个包中都存放着若干.go文件。
所有的.go文件,除了空行和注释,都应该在一行声明自己所属的包。
每个包都在一个单独的目录中。一个目录下不能有多个包,一个包也不能在多个目录下。同一个目录下所有.go文件必须属于同一个包。
包的命名:
一般来说,包的名字应当和目录名保持一致。
命名应当满足:全小写字母,简洁。
不同包的名字可以相同,因为导包的时候使用的是全路径。
main包:
编译程序会把main包编译成二进制可执行文件。
所有用Go编写的可执行文件都必须有main包。
main包中必须有main函数,否则无法编译。
一般会把main包文件所在的目录名作为可执行文件的文件名。
tips:
Go文档中,常用命令来称呼可执行文件。包用来指语义上可导入的功能单元。
3.2 导入
导入使用关键字import,导入多个包时使用()引起来。示例如下。
import( "fmt" "strings" )
导入的包分为两种:1、标准库包。2、用户自定义的包
假设现在要找包net/http。编译器会先去Go的安装目录找,如果找不到,再去$GO_PATH下的src里找,如果$GO_PATH有多个,那么会按顺序找。在这个过程中如果找到了就会停止,不再继续往后找。
如果没有找到,再对程序run或者build时就会出错。
远程导入:
Go能够导入分布式版本控制系统(DVCS)比如GitHub上的源代码库。需要指定导入路径。
import "github.com/spf13/viper"
go build能够根据导入路径去GO_PATH下寻找这个包。
事实上导入路径通常是一个URL,这时编译器使用go get命令将源代码保存在GO_PATH指定的路径中与URL所匹配的路径里。
go get 能够获取任何URL指定的包,也能获取已经导入的包依赖的其他包。具有递归特性。根据这种递归特性,就能够扫描包的依赖树,找到所有依赖包。
命名导入:
对于重名的包,可以采用命名导入。就是在包路径的左边指定一个名字,作为导入的包的新名字。
import( "fmt" myfmt "mylib/fmt" )
如果导入的包没有使用,编译器会直接报错!
但是有时候需要导入,但是不会使用这个包的标识符,可以使用空白标识符_来重命名。
空白标识符_的用法:
1. 给导入的包一个空名字。
2.忽略函数返回的不需要的值。
空白标识符后面 会多次使用。
3.3 函数init
init函数用于设置包、初始化变量以及其他要在程序运行之前优先完成的引导工作。
每个包可以有多个init函数,init函数会在main函数之前完成。
有时我们需要使用某个包的init函数为我们完成一些准备工作,但不需要这个包的其他功能。直接导入包会报错,因为我们没有使用,这时候就可以使用空白标识符。
3.4 Go工具包
大部分Go工具的命令都会接受一个包名作为参数。
1. 使用go build编译文件
示例:
go build hello
或者
go build hello.go
build命令的参数如果不写的话,Go会默认使用当前目录进行编译。
build命令的参数也可以使用通配符,比如
go build $GO_PATH/src/...
这代表编译src目录下的所有包。
2. 使用go clean删除编译文件
示例:
go clean hello.go
3. go run编译运行文件
文件需要先编译再运行,run命令能够直接完成这两个操作。
go run hello
4. go vet
该命令能帮开发者找出一部分代码的错误。包括:
Printf 类函数调用时,类型匹配错误的参数。
定义常用的方法时,方法签名的错误。
错误的结构标签。
没有指定字段名的结构字面量。
5. go fmt 代码格式化
go fmt能自动把代码的格式调整为Go源代码的格式。
// 使用go fmt前 if err != nil {return err} //使用 go fmt后 if err != nil { return err }
6. 获取Go语言的文档
从命令行获取文档 go doc:
假设想要看archive/tar包的相关文档,可以输入
go doc tar
会直接在终端打印出文档的内容
从浏览器获得文档:
godoc -http=:6060
这样就会导航到http://localhost:6060,从而查看文档。
go文档工具也能够查看开发者自己写的文档。也会包含到godoc里面。
写文档的规则如下:
在标识符之前,把文档作为注释加进去。注释可以用//也可以用/* */,取决于文档的长度。
// Retrieve 连接到配置库,收集各种链接设置、用户名和密码。这个函数在成功时 // 返回config 结构,否则返回一个错误。 func Retrieve() (config, error) { // ...省略 } /* 包usb 提供了用于调用USB 设备的类型和函数。想要与USB 设备创建一个新链接,使用NewConnection ... */ package usb
7. 共享代码需要注意的点
①因为导入包需要指定全路径,所以在分享自己的代码时,包名应该就是代码库的名字。源代码要放在代码库的根目录。防止导入时路径太长。
②包可以很小,go语言的包一般都不大。
③对代码进行go fmt,这样别人读起来也容易。
④给代码写文档,这样别人也能通过go doc查看。
3.7 依赖管理
现在使用go modules,这里用不到书上的方案了。
Go mod的存在,是官方强推,为了替代GOPATH而诞生的一个Go语言依赖库管理器。之前所有的包都丢在GOPATH中,烦skr人
这货最大的好处就是,我们依赖的包可以指定版本。
其次所有程序依赖的包,只会存在同一份。不会像npm那样,同一个包还能有n多个存在。这样我们的电脑就很省空间了
使用起来也非常简单,常用命令就一个go mod tidy,通俗来说就是将当前的库源码文件所依赖的包,全部安装并记录下来,多的包就删掉,少了的就自动补上
我们来实践操作下
进入我们的hello文件夹,并且执行go mod init即可
可以看到多出了一个go.mod文件和go.sum文件
go.mod文件是记录我们依赖库以及版本号
浙公网安备 33010602011771号