这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天。
今天,我主要学习了Go语言的一部分高级语法。
一、Go Goroutine
首先,我们需要分清楚“并发”和“并行”的特点(其实我们在操作系统里面已经学过了):“并发”是指若干个任务轮流短时间运行且快速切换,似乎在同时运行一样;而“并行”确实就是这些任务在一起运行(一般是基于多个处理器或者啥)。
Go语言的goroutine被广泛赞誉,因为它实现了对并发的原生支持,且资源消耗少(因此被广泛应用于Web开发,微服务等),我们用若干个例子来证明:
func output(x int) {
fmt.printf("%d\n", x)
}
func main() {
for i := 0; i < 10; i++ {
go output(i)
}
}
如果不使用go,那么这就是普通的一个循环,但是我们既然使用go创建了goroutine,那么就是实际上创建了10个线程,而线程是并发执行的,没有很明显的顺序。
显然,并发的特性在Web开发中有着广泛的应用:例如服务器需要应答一个请求,肯定是创建一个goroutine来处理(不然所有别的事物都得等它了,万一出个岔子就G了)
当然,并发的一些问题在Go中也存在,例如临界区这种事情,我们需要加锁来解决。
二、Go通道
为了实现goroutine之间的交互,我们常常使用通道的方式来进行。
通道分为无缓冲通道和有缓冲通道,如下所示:
ch1 := make(chan int)
ch2 := make(chan int, 10)
对于通道的读取则如下所示:
a := <-ch
ch <- b
此外,我们也可以对通道进行range操作,以及关闭之类的。
三、Go的包管理
从 Go v1.11开始,Go语言开始使用 Go moudle 进行包管理。在根目录下,我们执行 go mod init test-demo 即可生成一个 go.mod 文件,内部包含了项目信息和其依赖。通过这个文件,我们可以方便快捷的进行项目的包依赖的处理,并且实现一定的版本控制。
如果发现访问总库的速度过慢,我们也可以更改PROXY来处理,用一些更加近的源来代替。
四、Go代码测试
相比于 C/C++,Go语言提供了一套完整的单元测试系统,用于对代码的正确性进行测试。与此同时, 我们还可以检查代码覆盖率和代码效率,性能测试等。
如果有一个 calc.go 文件,那么测试文件就是 calc_test.go。如果 calc.go 内部有 Add,Div 两个函数,那么测试文件就应该如下:
func TestAdd(t *testing.T) {
}
func TestDiv(t *testing.T) {
}
那么,一旦执行 go test,这些测试函数都会被运行,并在运行后显示测试结果。