Go语言入门指南(下)
常用特性解析
基于协程的并发
goroutine
Go语言支持开启 goroutine 协程并通过 channel 来传递信息。
当一个程序启动时,其主函数即在一个单独的 goroutine 中运行。
要创建新的 goroutine 需要使用 go 语句,即为一个普通的函数或方法调用前加上关键字 go ,此后语句中的函数会在一个新创建的 goroutine 中运行,创建完成后程序会继续往下执行以实现并发。
一般仅有从主函数退出或者直接终止程序两种方式,能使一个 goroutine 来打断另一个的执行。
go func()
channel
一个 channel 是一个通信机制,它可以使一个 goroutine 通过它给另一个 goroutine 发送值信息。每个 channel 都有一个指定的数据类型,譬如 chan int 表示一个可以发送整型数据的 channel 。
要创建 channel ,需要使用函数 make(chan int) ,其后可以加上参数表明 channel 所带缓存大小,譬如 make(chan int, 10) 。
要从 channel 中获取信息或向其中传递信息,一般需要使用 <- 运算符。以 ch <- x 形式传入,以 <-ch 形式获取信息。
要关闭 channel ,使用 close() 函数。
当一个 channel 作为一个函数参数时,一般总是被专门用于只发送或者只接收。为此Go语言提供了单方向的 channel 类型, chan<- int 表示一个只发送整型数据的 channel ,只能发送不能接收,而 <-chan int 表示一个只接收整型数据的 channel ,只能接收不能发送。
ch := make(chan int)
ch <- x
x = <-ch
close(ch)
func squarer(out chan<- int, in <-chan int) {
for v := range in {
out <- v * v
}
close(out)
}
包和工具
每个Go语言源文件开头有包声明语句,如 package rand 语句形式指明此文件属于 rand 包。
要导入包,则需要 import 语句。如果同时导入两个有着名字相同的包,例如 math/rand 包和 crypto/rand 包,导入声明时须至少为一个同名包指定一个新的包名,进行导入包的重命名。
工具箱集合了一系列功能的命令集,可被视为一个包管理器。Go语言工具箱有许多子命令,例如 get 、 run 、 build 等,可以运行 go 或 go help 命令查看内置帮助文档。
import (
"crypto/rand"
mrand "math/rand"
)
测试
go test 命令是按照一定约定和组织来测试代码的程序。在包目录内,所有以 _test.go 为后缀名的源文件在执行 go build 时不会被构建成包的一部分。
而这类测试文件包含三类函数:测试函数、基准测试函数和示例函数。测试函数以 Test 为函数名前缀的函数,可以测试程序的逻辑行为是否正确;基准测试函数是以 Benchmark 为函数名前缀的函数,可以用于测量一些函数的性能;示例函数以 Example 为函数名前缀的函数。
使用 go test 命令,会遍历所有的 *_test.go 文件符合上述命名规则的函数,生成一个临时 main 包用于调用相应测试函数。其中,调用测试函数并报告测试结果,多次运行基准测试函数计算平均执行时间。