Go 初学者请教一个 channel 的 问题

2022-06-06 14:08:34 +08:00
 kashin0116

最近在看 gopl ,对第八章这个 crawl 的代码有个小小的问题。

func crawl(url string) []string {
	fmt.Println(url)
	list, err := links.Extract(url)
	if err != nil {
		log.Print(err)
	}
	return list
}

//!-crawl

//!+main
func main() {
	worklist := make(chan []string)

	// Start with the command-line arguments.
	go func() { worklist <- os.Args[1:] }()  // 为啥不需要 close buffer

	// Crawl the web concurrently.
	seen := make(map[string]bool)
	for list := range worklist {
		for _, link := range list {
			if !seen[link] {
				seen[link] = true
				go func(link string) {
					worklist <- crawl(link)
				}(link)
			}
		}
	}
}

go func() { worklist <- os.Args[1:] }() 这里应该是定义 unbuffered channel out 的一端,我看前面的示例对于 out 都要及时的 close ,这里似乎没有。

求指教。

1481 次点击
所在节点    Go 编程语言
4 条回复
Buges
2022-06-06 14:35:04 +08:00
close 是通知接收端发送已经结束的一种方式,如果你不需要或无法直接通知,那自然可以不用 close 。
你这个例子里有多个地方发送,谁也不知道什么时候结束,自然没法直接 close ,需要其他的方式通知。
还有一些情况如提前知道接受的数量,那自然也不用 close 。
seers
2022-06-06 14:44:05 +08:00
go 官方文档里面提过 channel 通常不必关闭,例子里面没有合适的时机关闭,否则会 panic ,所以就干脆不关
kashin0116
2022-06-06 14:49:44 +08:00
@Buges 谢谢!看漏掉了下面 loop 里还会利用这个 chan 。
```
go func(link string) {
worklist <- crawl(link)
}(link)
```
kashin0116
2022-06-06 14:50:14 +08:00
@seers 谢谢!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/857560

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX