• GO语言-select语句


    前言

            select是go语言当中提供的一个选择语句。select的语法类似switch语句,也属于控制语句。

    那为什么select语句我们没有放在和if、switch语句一起?

            因为select是配合channel通道使用的。每个 case 必须是一个通信操作,要么是发送要么是接收。

    特性总结

    • select只能用于channel操作,每个case都必须是一个channel;
    • 如果有多个case可以允许(channel没有阻塞),则随机选择一条case语句执行;
    • 如果没有case语句可以执行(channel发生阻塞),切没有default语句,则select语句会阻塞;
    • 如果没有case语句可以执行(channel发生阻塞),有default语句,则执行default语句;
    • 一般使用超时语句代替default语句;
    • 如果case语句中的channel为nil,则忽略该分支,相当于从select中删除了该分支;
    • 如果select语句在for循环中,一般不使用default语句,因为会引起CPU占用过高问题。

    select语句

    select语法格式

    1. select {
    2. case communication clause :
    3. statement(s);
    4. case communication clause :
    5. statement(s);
    6. /* 你可以定义任意数量的 case */
    7. default : /* 可选 */
    8. statement(s);
    9. }

    示例

    select只能用于channel操作,每个case都必须是一个channel。且channel是读取/写入都可以。

    1. func main() {
    2. ch1 := make(chan int)
    3. ch2 := make(chan string)
    4. go func() {
    5. ch1 <- 100
    6. }()
    7. go func() {
    8. num2 := <-ch2
    9. fmt.Println(num2)
    10. }()
    11. select {
    12. case num1 := <-ch1: //读取channel数据
    13. fmt.Println("ch1中的数据是:", num1)
    14. case ch2 <- "201": //channel写入数据
    15. fmt.Println("ch2有数据写入")
    16. }
    17. }

     

    随机性

    如果多条case语句都可以执行,则随机执行一条。

    示例中,两条case语句都可以执行。多次执行可以发现,case语句是随机执行其中一条的。

    1. func main() {
    2. ch1 := make(chan int)
    3. ch2 := make(chan int)
    4. go func() {
    5. ch1 <- 100
    6. }()
    7. go func() {
    8. ch2 <- 200
    9. }()
    10. select {
    11. case num1 := <-ch1:
    12. fmt.Println("ch1中的数据是:", num1)
    13. case num2 := <-ch2:
    14. fmt.Println("ch2中的数据是:", num2)
    15. }
    16. }

     

    死锁

    如果所有case语句都被阻塞,切没有default语句和超时语句,则程序会报错死锁。

    1. func main() {
    2. ch1 := make(chan int)
    3. ch2 := make(chan int)
    4. select {
    5. case <-ch1:
    6. fmt.Println("ch1")
    7. case <-ch2:
    8. fmt.Println("ch2")
    9. }
    10. }

     

    default语句

    如果所有case语句都阻塞,有default语句的话,就会执行default语句。

    要注意如果select语句在for循环中,default语句可能会造成CPU占用过高。

    1. func main() {
    2. ch1 := make(chan int)
    3. ch2 := make(chan int)
    4. select {
    5. case num1 := <-ch1:
    6. fmt.Println("ch1中的数据是:", num1)
    7. case num2 := <-ch2:
    8. fmt.Println("ch2中的数据是:", num2)
    9. default:
    10. fmt.Println("通道阻塞...default")
    11. }
    12. }

     

    超时语句

    一般使用超时语句代替default语句。

    1. func main() {
    2. ch1 := make(chan int)
    3. ch2 := make(chan int)
    4. select {
    5. case num1 := <-ch1:
    6. fmt.Println("ch1中的数据是:", num1)
    7. case num2 := <-ch2:
    8. fmt.Println("ch2中的数据是:", num2)
    9. case <-time.After(3 * time.Second):
    10. fmt.Println("timeout...")
    11. }
    12. }

     

  • 相关阅读:
    力扣labuladong一刷day13天双指针8道链表题
    linux高性能服务器
    Flink---1、概述、快速上手
    Hadoop学习记录3--HDFS知识补充
    毕设 JAVA.JSP网上选课系统
    【Spring boot 集成 Junit 单元测试】
    非常全的一份Python爬虫的Xpath博文
    ffmpeg.dll在哪个文件夹?怎么快速的修复ffmpeg.dll文件的丢失
    elementUI中form表单校验异常,开始就处罚了
    640. 求解方程
  • 原文地址:https://blog.csdn.net/qq522044637/article/details/125474800