go教程6

关闭信道和使用 for range 遍历信道

数据发送方可以关闭信道,通知接收方这个信道不再有数据发送过来。

当从信道接收数据时,接收方可以多用一个变量来检查信道是否已经关闭。

v, ok := <- ch

上面的语句里,如果成功接收信道所发送的数据,那么 ok 等于 true。而如果 ok 等于 false,说明我们试图读取一个关闭的通道。从关闭的信道读取到的值会是该信道类型的零值。例如,当信道是一个 int 类型的信道时,那么从关闭的信道读取的值将会是 0

package main
 
 
  
    

)
 
 
chnl 
 
 
  
    
 i 
 
 i 
 
 i
 

        chnl 
 i
    

    
chnl

}
 
 
  
    ch 
 
 

    
 
ch

    
 

        v
 ok 
 
ch
        
 ok 
 
 

            

        

        fmt
 v
 ok

    

}

在线运行程序

在上述的程序中,producer 协程会从 0 到 9 写入信道 chn1,然后关闭该信道。主函数有一个无限的 for 循环(第 16 行),使用变量 ok(第 18 行)检查信道是否已经关闭。如果 ok 等于 false,说明信道已经关闭,于是退出 for 循环。如果 ok 等于 true,会打印出接收到的值和 ok 的值。

Received  0 true  
Received  1 true  
Received  2 true  
Received  3 true  
Received  4 true  
Received  5 true  
Received  6 true  
Received  7 true  
Received  8 true  
Received  9 true

for range 循环用于在一个信道关闭之前,从信道接收数据。

接下来我们使用 for range 循环重写上面的代码。

package main
 
 
  
    

)
 
 
chnl 
 
 
  
    
 i 
 
 i 
 
 i
 

        chnl 
 i
    

    
chnl

}
 
 
  
    ch 
 
 

    
 
ch

    
 v 
 
 ch 

        fmt
v

    

}

在线运行程序

在第 16 行,for range 循环从信道 ch 接收数据,直到该信道关闭。一旦关闭了 ch,循环会自动结束,如果不关闭,for range循环会一直把线程卡死。该程序会输出:

Received  0  
Received  1  
Received  2  
Received  3  
Received  4  
Received  5  
Received  6  
Received  7  
Received  8  
Received  9

我们可以使用 for range 循环,重写信道的另一个示例这一节里面的代码,提高代码的可重用性。

如果你仔细观察这段代码,会发现获得一个数里的每位数的代码在 calcSquares 和 calcCubes 两个函数内重复了。我们将把这段代码抽离出来,放在一个单独的函数里,然后并发地调用它。

package main
 
 
  
    

)
 
 
number 
 dchnl 
 
 
  
    
 number 
 
 

        digit 
 number 
 

        dchnl 
 digit
        number 
 

    

    
dchnl

}
 
number 
 squareop 
 
 
  
    sum 
 

    dch 
 
 

    
 
number
 dch

    
 digit 
 
 dch 

        sum 
 digit 
 digit
    

    squareop 
 sum
}
 
 
number 
 cubeop 
 
 
  
    sum 
 

    dch 
 
 

    
 
number
 dch

    
 digit 
 
 dch 

        sum 
 digit 
 digit 
 digit
    

    cubeop 
 sum
}
 
 
 
  
    number 
 

    sqrch 
 
 

    cubech 
 
 

    
 
number
 sqrch

    
 
number
 cubech

    squares
 cubes 
 
sqrch
 
cubech
    fmt
 squares
cubes

}

在线运行程序

上述程序里的 digits 函数,包含了获取一个数的每位数的逻辑,并且 calcSquares 和 calcCubes 两个函数并发地调用了 digits。当计算完数字里面的每一位数时,第 13 行就会关闭信道。calcSquares 和 calcCubes 两个协程使用 for range 循环分别监听了它们的信道,直到该信道关闭。程序的其他地方不变,该程序同样会输出:

Final output 1536
本教程的内容到此结束
posted @   易先讯  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示