0
点赞
收藏
分享

微信扫一扫

go获取需要搜索的数据源列表

代码清单 2-14 main.go:第 17 行到第 21 行  

17 // main 是整个程序的入口  

18 func main() {  

19 // 使用特定的项做搜索  

20 search.Run("president")  

21 }  

Run函数做的第一件事情就是获取数据源feeds列表。这些数据源从互联网上抓取数据,之后对数据使用特定的搜索项进行匹配,如代码清单 2-15 所示。  

代码清单 2-15 search/search.go:第 13 行到第 17 行  

13 // 获取需要搜索的数据源列表  

14 feeds, err := RetrieveFeeds()  

15 if err != nil {  

16 log.Fatal(err)  

17 }  

这里有几个值得注意的重要概念。第 14 行调用了search包的RetrieveFeeds函数。这个函数返回两个值。第一个返回值是一组Feed类型的切片。切片是一种实现了一个动态数组的引用类型。在 Go 语言里可以用切片来操作一组数据。第 4 章会进一步深入了解有关切片的细节。  

第二个返回值是一个错误值。在第 15 行,检查返回的值是不是真的是一个错误。如果真的发生错误了,就会调用log包里的Fatal函数。Fatal函数接受这个错误的值,并将这个错误

在终端窗口里输出,随后终止程序。  

不仅仅是Go语言,很多语言都允许一个函数返回多个值。一般会像RetrieveFeeds函数这样声明一个函数返回一个值和一个错误值。如果发生了错误,永远不要使用该函数返回的另一个值①。这时必须忽略另一个值,否则程序会产生更多的错误,甚至崩溃。  

让我们仔细看看从函数返回的值是如何赋值给变量的,如代码清单 2-16 所示。  

代码清单 2-16 search/search.go:第 13 行到第 14 行  

13 // 获取需要搜索的数据源列表  

14 feeds, err := RetrieveFeeds()  

这里可以看到简化变量声明运算符(:=)。这个运算符用于声明一个变量,同时给这个变量

①这个说法并不严格成立,Go 标准库中的 io.Reader.Read 方法就允许同时返回数据和错误。但是,如果是自己实现的函数,要尽量遵守这个原则,保持含义足够明确。——译者注

赋予初始值。编译器使用函数返回值的类型来确定每个变量的类型。简化变量声明运算符只是一种简化记法,让代码可读性更高。这个运算符声明的变量和其他使用关键字 var 声明的变量没有任何区别。  

现在我们得到了数据源列表,进入到后面的代码,如代码清单 2-17 所示。  

代码清单 2-17 search/search.go:第 19 行到第 20 行  

19 // 创建一个无缓冲的通道,接收匹配后的结果  

20 results := make(chan *Result)  

在第 20 行,我们使用内置的make函数创建了一个无缓冲的通道。我们使用简化变量声明运算符,在调用make的同时声明并初始化该通道变量。根据经验,如果需要声明初始值为零值的变量,应该使用 var 关键字声明变量;如果提供确切的非零值初始化变量或者使用函数返回值创建变量,应该使用简化变量声明运算符。  

在 Go 语言中,通道(channel)和映射(map)与切片(slice)一样,也是引用类型,不过通道本身实现的是一组带类型的值,这组值用于在 goroutine 之间传递数据。通道内置同步机制,从而保证通信安全。在第 6 章中,我们会介绍更多关于通道和 goroutine 的细节。  

之后两行是为了防止程序在全部搜索执行完之前终止,如代码清单 2-18 所示。  

代码清单 2-18 search/search.go:第 22 行到第 27 行  

22 // 构造一个wait group,以便处理所有的数据源  

23 var waitGroup sync.WaitGroup  

24  

25 // 设置需要等待处理  

26 // 每个数据源的goroutine的数量  

27 waitGroup.Add(len(feeds))  

在 Go 语言中,如果main函数返回,整个程序也就终止了。Go 程序终止时,还会关闭所有之前启动且还在运行的 goroutine。写并发程序的时候,最佳做法是,在main函数返回前,清理并终止所有之前启动的 goroutine。编写启动和终止时的状态都很清晰的程序,有助减少 bug,防止资源异常。  

这个程序使用sync包的WaitGroup跟踪所有启动的 goroutine。非常推荐使用WaitGroup来跟踪 goroutine 的工作是否完成。WaitGroup是一个计数信号量,我们可以利用它来统计所有的 goroutine 是不是都完成了工作。  

举报

相关推荐

0 条评论