读Go in action源码chapter1
最近买了本Go in action学习,以此记录学习日志。
chapter1源码部分:
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func printer(ch chan int) {
for i := range ch {
fmt.Printf("Received %d ", i)
}
wg.Done()
}
// main is the entry point for the program.
func main() {
c := make(chan int)
go printer(c)
wg.Add(1)
// Send 10 integers on the channel.
for i := 1; i <= 10; i++ {
c <- i
}
close(c)
wg.Wait()
}
以上运行结果为
Received 1 Received 2 Received 3 Received 4 Received 5 Received 6 Received 7 Received 8 Received 9 Received 10
分析:
一、
第1行:main函数保存在包里面,如果main函数不在main包里,构建工具就不会生成可执行文件。
包的名字类似命名空间,可间接访问包内声明标识符,所有处于同一个文件夹里的代码文件,必须使用同一个包名,按照惯例,包和文件夹同名。
第3~6行:import导入一段代码,使其可以访问其中的标识符,如类型,函数,常量和接口。
第8行:声明一个sync包里的WaitGroup类型的变量,WaitGroup是一个计数信号量,可以利用它来跟踪goroutine是否完成。
二、
再看main函数(程序入口)
第19行:创建一个无缓冲的通道,接收匹配后的结果(使用make的同时声明并初始化该通道变量)
在Go语言中,channel和map与slice一样,均为引用类型,通道本身实现的是一组带类型的值,这组值用于在goroutine之间传递数据,通道内置同步机制,从而保证安全。
第20行:使用关键字go启动一个goroutine ,一个goroutine是一个独立于其它函数运行的函数(与其他goroutine并行执行,同时也和主程序main并行执行),该goroutine调用printer函数。
第21行:设置需要等待处理,将WaitGroup变量设置为将要启动的goroutine的数量,每个goroutine完成工作后,会递减WaitGroup变量的计数值,当这个值递减为0时,就知道所有工作做完了。
第24~26行:将循环变量i写入通道
第27行:关闭通道。
第28行:等待所有任务完成,WaitGroup的Wait方法,会导致goroutine阻塞,直到WaitGroup内部的计数到达0.
三、
第10行:定义了printer方法,参数为一个int类型通道
第11行:for range会一直阻塞,直到有结果写入通道,一旦mian函数中close(c)关闭了通道,for range就会停止。
第14行:递减WaitGroup计数。
吐槽:还是在书上记笔记实在,写博客耗时间,囧。