读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 

分析:

一、读Go in action源码chapter1_第1张图片

第1行:main函数保存在包里面,如果main函数不在main包里,构建工具就不会生成可执行文件。

              包的名字类似命名空间,可间接访问包内声明标识符,所有处于同一个文件夹里的代码文件,必须使用同一个包名,按照惯例,包和文件夹同名。

第3~6行:import导入一段代码,使其可以访问其中的标识符,如类型,函数,常量和接口。

第8行:声明一个sync包里的WaitGroup类型的变量,WaitGroup是一个计数信号量,可以利用它来跟踪goroutine是否完成。

 

二、读Go in action源码chapter1_第2张图片

再看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.

三、读Go in action源码chapter1_第3张图片

第10行:定义了printer方法,参数为一个int类型通道

第11行:for range会一直阻塞,直到有结果写入通道,一旦mian函数中close(c)关闭了通道,for range就会停止。

第14行:递减WaitGroup计数。

 

吐槽:还是在书上记笔记实在,写博客耗时间,囧。

你可能感兴趣的:(go)