教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 golang 学习(三十)管道(channel)介绍以及应用

golang 学习(三十)管道(channel)介绍以及应用

发布时间:2021-12-16   编辑:jiaochengji.com
教程集为您提供golang 学习(三十)管道(channel)介绍以及应用等资源,欢迎您收藏本站,我们将为您提供最新的golang 学习(三十)管道(channel)介绍以及应用资源
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"/></svg><h1>管道(channel)介绍以及应用</h1> <ol><li>管道是 Golang 在语言级别上提供的 goroutine 间的通讯方式,我们可以使用 channel 在 多个 goroutine之间传递消息。如果说 goroutine 是 Go 程序并发的执行体,channel 就是它们 之间的连接。channel 是可以让一个goroutine 发送特定值到另一个 gorutine 的通信机制</li><li>Golang 的并发模型是 CSP(Comunicating Sequential Processes),提倡通过通信共享内 存而不是通过共享内存而实现通信。</li><li>Go 语言中的管道(channel)是一种特殊的类型。管道像一个传送带或者队列,总是遵 循先入先出(First In First Out)的规则,保证收发数据的顺序。每一个管道都是一个具体类 型的导管,也就是声明 chanel 的时候需要为其指定元素类型</li></ol><h3>channel 类型</h3>

channel 是一种类型,一种引用类型
var 变量 chan 元素类型

<pre><code class="lang-go hljs"><span class="token keyword">var</span> ch1 <span class="token keyword">chan</span> <span class="token builtin">int</span> <span class="token comment">// 声明一个传递整型的管道</span> <span class="token keyword">var</span> ch2 <span class="token keyword">chan</span> bol <span class="token comment">// 声明一个传递布尔型的管道</span> <span class="token keyword">var</span> ch3 <span class="token keyword">chan</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">int</span> <span class="token comment">// 声明一个传递 int 切片的管道</span> </code></pre> <h3>
创建 channel</h3>

声明的管道后需要使用 make 函数初始化之后才能使用
make(chan 元素类型, 容量)

<pre><code class="lang-go hljs"><span class="token keyword">var</span> ch <span class="token operator">=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token builtin">int</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token comment">//创建一个能存储 4 个 int 类型数据的管道</span> </code></pre> <h2>
chanel 操作</h2>

管道有发送(send)、接收(recive)和关闭(close)三种操作
发送和接收都使用<-符号

<pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token function">TestChannel</span><span class="token punctuation">(</span>t <span class="token operator">*</span>testing<span class="token punctuation">.</span>T<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//channel 管道 是引用数据类型 先入先出</span> <span class="token keyword">var</span> ch <span class="token operator">=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token builtin">int</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token comment">//创建管道</span> ch <span class="token operator"><-</span> <span class="token number">10</span> <span class="token comment">//把 10 发送到 ch 中</span> a <span class="token operator">:=</span> <span class="token operator"><-</span>ch <span class="token comment">//获取管道的数据</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span> <span class="token comment">//10</span> <span class="token comment">//打印管道的长度 容量</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"值 %v 长度 %v 容量 %v \n"</span><span class="token punctuation">,</span> ch<span class="token punctuation">,</span> <span class="token function">len</span><span class="token punctuation">(</span>ch<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">cap</span><span class="token punctuation">(</span>ch<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment">//值 0xc000014200 长度 0 容量 4</span> ch <span class="token operator"><-</span> <span class="token number">20</span> <span class="token operator"><-</span>ch <span class="token punctuation">}</span> </code></pre>

关闭管道 close(ch)
关于关闭管道需要注意的事情是,只有在通知接收方 goroutine 所有的数据都发送完毕的时
候才需要关闭管道。管道是可以被垃圾回收机制回收的,它和关闭文件是不一样的,在结束
操作之后关闭文件是必须要做的,但关闭管道不是必须的。
关闭后的管道有以下特点:

<ol><li>对一个关闭的管道再发送值就会导致 panic。</li><li>对一个关闭的管道进行接收会一直获取值直到管道为空。</li><li>对一个关闭的并且没有值的管道执行接收操作会得到对应类型的零值。</li><li>关闭一个已经关闭的管道会导致 panic。</li></ol><h2>
管道阻塞</h2>

无缓冲的管道:
如果创建管道的时候没有指定容量,那么我们可以叫这个管道为无缓冲的管道
无缓冲的管道又称为阻塞的管道

<pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token function">TestChannel</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//无缓冲的管道</span> ch <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token builtin">int</span><span class="token punctuation">)</span> ch <span class="token operator"><-</span> <span class="token number">10</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"发送成功"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">//编译报错 fatl ero: al gorutines are asleep - deadlock!</span> <span class="token comment">//有缓冲的管道</span> ch <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token builtin">int</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">)</span> ch <span class="token operator"><-</span> <span class="token number">10</span> a1<span class="token operator">:=</span><span class="token operator"><-</span>ch fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>a1<span class="token punctuation">)</span><span class="token comment">//10</span> a2<span class="token operator">:=</span><span class="token operator"><-</span>ch <span class="token comment">//管道的阻塞 在没有使用协程的情况下,如果我们的管道数据已经全部取出,再取就会报告 deadlock</span> </code></pre>

只要管道的容量大于零,那么该管道就是有缓冲的管道,管道的容量表示管道中能存放元素
的数量。就像你小区的快递柜只有那么个多格子,格子满了就装不下了,就阻塞了,等到别
人取走一个快递员就能往里面放一个。

<h3>
for range,for i 从管道循环取值</h3> <pre><code class="lang-go hljs"><span class="token keyword">var</span> ch <span class="token operator">=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token builtin">int</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token keyword">for</span> i <span class="token operator">:=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> <span class="token number">4</span><span class="token punctuation">;</span> i<span class="token operator"> </span> <span class="token punctuation">{</span> ch <span class="token operator"><-</span> i <span class="token punctuation">}</span> <span class="token function">close</span><span class="token punctuation">(</span>ch<span class="token punctuation">)</span><span class="token comment">//for range 循环需要执行关闭管道,否则会报deallock</span> <span class="token comment">//循环遍历管道的值,注意管道没有key</span> <span class="token keyword">for</span> v <span class="token operator">:=</span> <span class="token keyword">range</span> ch <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">for</span> i <span class="token operator">:=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> <span class="token number">4</span><span class="token punctuation">;</span> i<span class="token operator"> </span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token operator"><-</span>ch<span class="token punctuation">)</span> <span class="token punctuation">}</span> </code></pre> <h3>channel管道和gorouting协程结合应用</h3> <pre><code class="lang-go hljs"><span class="token comment">//二个协程 二个管道 边写数据 边读数据</span> <span class="token keyword">import</span> <span class="token punctuation">(</span> <span class="token string">"fmt"</span> <span class="token string">"sync"</span> <span class="token string">"testing"</span> <span class="token punctuation">)</span> <span class="token keyword">func</span> <span class="token function">ReadDate</span><span class="token punctuation">(</span>ch <span class="token keyword">chan</span> <span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> v <span class="token operator">:=</span> <span class="token keyword">range</span> ch <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"读取管道数据%v\n"</span><span class="token punctuation">,</span>v<span class="token punctuation">)</span> <span class="token punctuation">}</span> wg<span class="token punctuation">.</span><span class="token function">Done</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">WriteData</span><span class="token punctuation">(</span>ch <span class="token keyword">chan</span> <span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> i <span class="token operator">:=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> <span class="token number">10</span><span class="token punctuation">;</span> i<span class="token operator"> </span> <span class="token punctuation">{</span> ch<span class="token operator"><-</span>i fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"写入管道数据%v\n"</span><span class="token punctuation">,</span>i<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token function">close</span><span class="token punctuation">(</span>ch<span class="token punctuation">)</span> wg<span class="token punctuation">.</span><span class="token function">Done</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> wg sync<span class="token punctuation">.</span>WaitGroup <span class="token keyword">func</span> <span class="token function">TestChannel</span><span class="token punctuation">(</span>t <span class="token operator">*</span>testing<span class="token punctuation">.</span>T<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> v <span class="token operator">:=</span> <span class="token keyword">range</span> ch <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> ch1 <span class="token operator">=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token builtin">int</span><span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">)</span> wg<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword">go</span> <span class="token function">WriteData</span><span class="token punctuation">(</span>ch1<span class="token punctuation">)</span> wg<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword">go</span> <span class="token function">ReadDate</span><span class="token punctuation">(</span>ch1<span class="token punctuation">)</span> wg<span class="token punctuation">.</span><span class="token function">Wait</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> </code></pre> <h3>求10000内的素数</h3> <pre><code class="lang-go hljs"><span class="token keyword">import</span> <span class="token punctuation">(</span> <span class="token string">"fmt"</span> <span class="token string">"sync"</span> <span class="token string">"testing"</span> <span class="token punctuation">)</span> <span class="token comment">//前10000数据存入管道</span> <span class="token keyword">func</span> <span class="token function">putNum</span><span class="token punctuation">(</span>ch <span class="token keyword">chan</span> <span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> i <span class="token operator">:=</span> <span class="token number">2</span><span class="token punctuation">;</span> i <span class="token operator"><=</span> <span class="token number">10000</span><span class="token punctuation">;</span> i<span class="token operator"> </span> <span class="token punctuation">{</span> ch <span class="token operator"><-</span> i <span class="token punctuation">}</span> <span class="token function">close</span><span class="token punctuation">(</span>ch<span class="token punctuation">)</span> wg<span class="token punctuation">.</span><span class="token function">Done</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">//生成素数</span> <span class="token keyword">func</span> <span class="token function">DoNum</span><span class="token punctuation">(</span>ch <span class="token keyword">chan</span> <span class="token builtin">int</span><span class="token punctuation">,</span> num <span class="token keyword">chan</span> <span class="token builtin">int</span><span class="token punctuation">,</span> status <span class="token keyword">chan</span> <span class="token builtin">bool</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> v <span class="token operator">:=</span> <span class="token keyword">range</span> ch <span class="token punctuation">{</span> <span class="token keyword">var</span> flag <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token keyword">for</span> i <span class="token operator">:=</span> <span class="token number">2</span><span class="token punctuation">;</span> i <span class="token operator"><</span> v<span class="token punctuation">;</span> i<span class="token operator"> </span> <span class="token punctuation">{</span> <span class="token keyword">if</span> v<span class="token operator">%</span>i <span class="token operator">==</span> <span class="token number">0</span> <span class="token punctuation">{</span> flag <span class="token operator">=</span> <span class="token boolean">false</span> <span class="token keyword">break</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> flag <span class="token punctuation">{</span> num <span class="token operator"><-</span> v <span class="token comment">//num素数</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> status <span class="token operator"><-</span> <span class="token boolean">true</span> <span class="token comment">//记录管道执行状态</span> wg<span class="token punctuation">.</span><span class="token function">Done</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">//打印素数</span> <span class="token keyword">func</span> <span class="token function">PrintNum</span><span class="token punctuation">(</span>ch <span class="token keyword">chan</span> <span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> v <span class="token operator">:=</span> <span class="token keyword">range</span> ch <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span> <span class="token punctuation">}</span> wg<span class="token punctuation">.</span><span class="token function">Done</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> wg sync<span class="token punctuation">.</span>WaitGroup <span class="token keyword">func</span> <span class="token function">TestChannel</span><span class="token punctuation">(</span>t <span class="token operator">*</span>testing<span class="token punctuation">.</span>T<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> intChan <span class="token operator">=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token builtin">int</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span> <span class="token keyword">var</span> primeChan <span class="token operator">=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token builtin">int</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span> <span class="token keyword">var</span> exitChan <span class="token operator">=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token builtin">bool</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span> wg<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword">go</span> <span class="token function">putNum</span><span class="token punctuation">(</span>intChan<span class="token punctuation">)</span> <span class="token keyword">for</span> i <span class="token operator">:=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> <span class="token number">16</span><span class="token punctuation">;</span> i<span class="token operator"> </span> <span class="token punctuation">{</span><span class="token comment">//开启16 个协程处理素数判断</span> wg<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword">go</span> <span class="token function">DoNum</span><span class="token punctuation">(</span>intChan<span class="token punctuation">,</span> primeChan<span class="token punctuation">,</span> exitChan<span class="token punctuation">)</span> <span class="token punctuation">}</span> wg<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token comment">//判断primeChan管道执行完成后关闭</span> <span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> i <span class="token operator">:=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> <span class="token number">16</span><span class="token punctuation">;</span> i<span class="token operator"> </span> <span class="token punctuation">{</span> <span class="token operator"><-</span>exitChan <span class="token punctuation">}</span> <span class="token function">close</span><span class="token punctuation">(</span>primeChan<span class="token punctuation">)</span> wg<span class="token punctuation">.</span><span class="token function">Done</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span> wg<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword">go</span> <span class="token function">PrintNum</span><span class="token punctuation">(</span>primeChan<span class="token punctuation">)</span> wg<span class="token punctuation">.</span><span class="token function">Wait</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> </code></pre> <h2>单向管道</h2>

有的时候我们会将管道作为参数在多个任务函数间传递,很多时候我们在不同的任务函数中 使用管道都会对其进行限制,比如限制管道在函数中只能发送或只能接收

<pre><code class="lang-go hljs"><span class="token comment">//定义双向管道</span> <span class="token keyword">var</span> myChan <span class="token operator">=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token builtin">int</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token comment">//定义只读的channel</span> <span class="token keyword">var</span> readChan <span class="token operator">=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token operator"><-</span><span class="token keyword">chan</span> <span class="token builtin">int</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token operator"><-</span>readChan <span class="token operator"><-</span>readChan <span class="token comment">//定义只写的channel</span> <span class="token keyword">var</span> writeChan <span class="token operator">=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span><span class="token operator"><-</span> <span class="token builtin">int</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span> writeChan<span class="token operator"><-</span><span class="token number">10</span> writeChan<span class="token operator"><-</span><span class="token number">20</span> </code></pre> <h2>
select 多路复用</h2> <ol><li>传统的方法在遍历管道时,如果不关闭会阻塞而导致 deadlock,在实际开发中,可能我们不好确定什么关闭该管道</li><li>Go 内置了 select 关键字,可以同时响应多个管道的操作</li><li>使用 select 语句能提高代码的可读性。
• 可处理一个或多个 channel 的发送/接收操作。
• 如果多个 case 同时满足,select 会随机选择一个。
• 对于没有 case 的 select{}会一直等待,可用于阻塞 main 函数</li></ol><pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token function">TestChan</span><span class="token punctuation">(</span>t <span class="token operator">*</span>testing<span class="token punctuation">.</span>T<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//select 多路复用 在某些场景下我们需要同时从多个 channel接收数据,这个时候就可以用到select多路复用</span> <span class="token keyword">var</span> intChan <span class="token operator">=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token builtin">int</span><span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">)</span> <span class="token keyword">var</span> stringChan <span class="token operator">=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token builtin">string</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">)</span> <span class="token keyword">for</span> i <span class="token operator">:=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> <span class="token number">10</span><span class="token punctuation">;</span> i<span class="token operator"> </span> <span class="token punctuation">{</span> intChan<span class="token operator"><-</span>i <span class="token punctuation">}</span> <span class="token keyword">for</span> i <span class="token operator">:=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> <span class="token number">6</span><span class="token punctuation">;</span> i<span class="token operator"> </span> <span class="token punctuation">{</span> stringChan<span class="token operator"><-</span><span class="token string">"hello"</span> <span class="token operator"> </span>fmt<span class="token punctuation">.</span><span class="token function">Sprintf</span><span class="token punctuation">(</span><span class="token string">"%d"</span><span class="token punctuation">,</span>i<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">//使用select来获取channel里面的数据的时候不需要关闭channel,如果关闭会出现死循环</span> <span class="token keyword">for</span><span class="token punctuation">{</span> <span class="token keyword">select</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> v<span class="token operator">:=</span><span class="token operator"><-</span>intChan<span class="token punctuation">:</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"读取int值%v\n"</span><span class="token punctuation">,</span>v<span class="token punctuation">)</span> time<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>Millisecond<span class="token operator">*</span><span class="token number">50</span><span class="token punctuation">)</span> <span class="token keyword">case</span> v<span class="token operator">:=</span><span class="token operator"><-</span>stringChan<span class="token punctuation">:</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"读取string值%v\n"</span><span class="token punctuation">,</span>v<span class="token punctuation">)</span> time<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>Millisecond <span class="token operator">*</span> <span class="token number">50</span><span class="token punctuation">)</span> <span class="token keyword">default</span><span class="token punctuation">:</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"结束"</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> <h2>
Goroutine Recover 解决协程中出现的 Panic</h2> <pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token function">sayNum</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> i <span class="token operator">:=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> <span class="token number">10</span><span class="token punctuation">;</span> i<span class="token operator"> </span> <span class="token punctuation">{</span> time<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>Second<span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">,</span>i<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//defer recover 处理异常</span> <span class="token keyword">defer</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> err<span class="token operator">:=</span><span class="token function">recover</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>err<span class="token operator">!=</span><span class="token boolean">nil</span><span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"程序异常"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">var</span> myMap <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">int</span><span class="token punctuation">]</span><span class="token builtin">string</span> myMap<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"hello world"</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">TestChan</span><span class="token punctuation">(</span>t <span class="token operator">*</span>testing<span class="token punctuation">.</span>T<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">go</span> <span class="token function">sayNum</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">go</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> </code></pre> 到此这篇关于“golang 学习(三十)管道(channel)介绍以及应用”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
【文末有惊喜!】一文读懂golang channel
Go 语言为什么这么快,带你详细了解Golang CSP并发模型
图解 Go 并发编程
golang知识点
golang学习笔记(二)—— 深入golang中的协程
golang基础教程
golang 面试题(三)管道chan
golang channel的使用以及调度原理
字节跳动的 Go 语言面试会问哪些问题?
GO语言学习-并发

[关闭]
~ ~