首页 > 其他 > 详细

golang select case 用法

时间:2021-05-11 16:27:38      阅读:11      评论:0      收藏:0      [点我收藏+]

 

package main
import {

        "fmt"

        "time"
)
 
func main() {
        ch1 := make(chan int)
        ch2 := make(chan int)
 
        go func(ch chan int) { <-ch }(ch1)
        go func(ch chan int) { ch <- 2 }(ch2)
 
        time.Sleep(time.Millisecond)
 
        for {
                select {
                case ch1 <- 1:
                        fmt.Println("Send operation on ch1 works!")
                        //continue
                case <-ch2:
                        fmt.Println("Receive operation on ch2 works!")
                        continue
                default:
                        fmt.Println("Exit now!")
                        return
                }
              fmt.Println("bbbbbbb")
        }
        //i := 1;
        //for {
        //    i++
        //    fmt.Println(i)
        //    if i > 3 {
        //      break
        //    }

        //}
}

  

一、switch语句

switch语句提供了一个多分支条件执行的方法。每一个case可以携带一个表达式或一个类型说明符。前者又可被简称为case表达式。因此,Go语言的switch语句又分为表达式switch语句和类型switch语句。

Go会依照从上至下的顺序对每一条case语句中case表达式进行求值,只要被发现其表达式与switch表达式的结果相同,该case语句就会被选中。其余的case语句会被忽略。   与if相同,switch语句还可以包含初始化字句,且其出现位置和写法如出一辙:

var name string 
... 
switch name { 
case "Golang": 
 fmt.Println("Golang") 
case "Rust": 
 fmt.Println("Rust") 
default: 
 fmt.Println("PHP是世界上最好的语言") 
} 

 

二、select语句

注意到 select 的代码形式和 switch 非常相似, 不过 select 的 case 里的操作语句只能是【IO 操作】 。

 

break语句也可以被包含在select语句中的case语句中。它的作用是立即结束当前的select语句的执行。不论其所属的case语句中是否还有未被执行的语句。

---------------------

 

golang 的 select 的功能和 select, poll, epoll 相似, 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作。

示例:

ch1 := make (chan int, 1)
ch2 := make (chan int, 1)

...

select {
case <-ch1:
    fmt.Println("ch1 pop one element")
case <-ch2:
    fmt.Println("ch2 pop one element")
}

注意到 select 的代码形式和 switch 非常相似, 不过 select 的 case 里的操作语句只能是【IO 操作】 。

此示例里面 select 会一直等待等到某个 case 语句完成, 也就是等到成功从 ch1 或者 ch2 中读到数据。 则 select 语句结束。

【使用 select 实现 timeout 机制】

如下:

timeout := make (chan bool, 1)
go func() {
    time.Sleep(1e9) // sleep one second
    timeout <- true
}()
ch := make (chan int)
select {
case <- ch:
case <- timeout:
    fmt.Println("timeout!")
}

当超时时间到的时候,case2 会操作成功。 所以 select 语句则会退出。 而不是一直阻塞在 ch 的读取操作上。 从而实现了对 ch 读取操作的超时设置。

下面这个更有意思一点。

当 select 语句带有 default 的时候:

ch1 := make (chan int, 1)
ch2 := make (chan int, 1)

select {
case <-ch1:
    fmt.Println("ch1 pop one element")
case <-ch2:
    fmt.Println("ch2 pop one element")
default:
    fmt.Println("default")
}

此时因为 ch1 和 ch2 都为空,所以 case1 和 case2 都不会读取成功。 则 select 执行 default 语句。

就是因为这个 default 特性, 我们可以使用 select 语句来检测 chan 是否已经满了。

如下:

ch := make (chan int, 1)
ch <- 1
select {
case ch <- 2:
default:
    fmt.Println("channel is full !")
}

因为 ch 插入 1 的时候已经满了, 当 ch 要插入 2 的时候,发现 ch 已经满了(case1 阻塞住), 则 select 执行 default 语句。 这样就可以实现对 channel 是否已满的检测, 而不是一直等待。

比如我们有一个服务, 当请求进来的时候我们会生成一个 job 扔进 channel, 由其他协程从 channel 中获取 job 去执行。 但是我们希望当 channel 瞒了的时候, 将该 job 抛弃并回复 【服务繁忙,请稍微再试。】 就可以用 select 实现该需求。

golang select case 用法

原文:https://www.cnblogs.com/oxspirt/p/14755036.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!