Bladeren bron

Update 14.2.md

glight2000 10 jaren geleden
bovenliggende
commit
08ed796b24
1 gewijzigde bestanden met toevoegingen van 57 en 0 verwijderingen
  1. 57 0
      eBook/14.2.md

+ 57 - 0
eBook/14.2.md

@@ -401,6 +401,63 @@ func suck(ch chan int) {
 
 ## 14.2.10 给通道使用For循环
 
+`for`循环的`range`语句可以用在通道`ch`上,便可以从通道中获取值,像这样:
+```go
+for v := range ch {
+	fmt.Printf("The value is %v\n", v)
+}
+```
+它从指定通道中读取数据直到通道关闭,才继续执行下边的代码。很明显,另外一个协程必须写入`ch`(不然代码就阻塞在for循环了),而且必须在写入完成后才关闭。`suck`函数可以这样写,且在协程中调用这个动作,程序变成了这样:
+
+示例 14.6-[channel_idiom2.go](examples/chapter_14/channel_idiom2.go)
+```go
+package main
+
+import (
+	"fmt"
+	"time"
+)
+
+func main() {
+	suck(pump())
+	time.Sleep(1e9)
+}
+
+func pump() chan int {
+	ch := make(chan int)
+	go func() {
+		for i := 0; ; i++ {
+			ch <- i
+		}
+	}()
+	return ch
+}
+
+func suck(ch chan int) {
+	go func() {
+		for v := range ch {
+			fmt.Println(v)
+		}
+	}()
+}
+```
+
+习惯用法:通道迭代模式
+
+这个模式用到了前边示例[14.6](exercises/chapter_14/producer_consumer.go)中的模式,通常,需要从包含了地址索引字段items的容器给通道填入元素。为容器的类型定义一个方法`Iter()`,返回一个只读的通道(参见章节[14.2.8](14.2.8.md))items,如下:
+```go
+func (c *container) Iter () <- chan items {
+	ch := make(chan item)
+	go func () {
+		for i:= 0; i < c.Len(); i++{	// or use a for-range loop
+			ch <- c.items[i]
+		}
+	} ()
+	return ch
+}
+```
+
+
 
 ## 链接