Go关键字--select


友情推广
在这里插入图片描述

select

在golang中使用select可以实现一个条件选择器,select与switch关键字有着类似的效果,都是实现了一个条件选择器,但是select中的判断条件必须是通信操作,golang中的通信操作是 <- 。当通道在操作符左侧时,表示向通道中写入信息,当通道在操作符右侧时,表示读取通道信息。

// 写入操作
通道 <-// 读取操作
变量 <- 通道

编写select条件选择器的语法格式是:

select {
    case <- ch1:
        // 读取通道ch1,读取成功,执行这个分支。
        // do something
    case val := <- ch2:
        // 读取通道ch2,读取成功,执行这个分支。
        //  do something
    case ch3 ->:
        // 想
        // do something
    default:
        // do something
}

在golang中,支持通信操作的类型只有chan,所以select中的case条件只能是对chan类型变量的读写操作。由于chan类型变量的读写操作可能会引起阻塞,为了在使用select选择器时不陷入阻塞状态,可以在select代码块中添加default关键字,当case条件全部都不满足时,默认进入default分支,执行完default分支的代码后,退出select选择器。

下边来一个例子来使用select实现条件选择。

package main

import (
	"fmt"
	"time"
)

func main() {
	fmt.Println("开始时间:", time.Now().Format("2006-01-02 15:04:05"))
	select {
	case <-time.After(time.Second * 2):
		fmt.Println("2秒后的时间:", time.Now().Format("2006-01-02 15:04:05"))
	}
}

输出信息是:

开始时间: 2017-09-15 23:23:10
2秒后的时间: 2017-09-15 23:23:12

time.After函数返回一个通道类型的变量,然后在case中从这个通道中读取信息,如果没有协程给这个通道发送信息,那么case将会一直阻塞。在调用After函数时,传入了一个时长作为参数,意思是从调用After函数算起,到设定的市场后,有协程将会向这个通道发送一条消息。当通道收到消息后,这个case条件满足,这个case分支下的代码将会被执行。

当select中同一时间,有多个case满足条件时,select会选择哪一个分支执行,还是执行多个分支呢?答案是:随机选择一个满足满足条件的case分支执行,这个分支执行完成后,退出select选择器。请记住:是随机选择一个满足条件的case分支执行。下边请看示例:

package main

import (
	"fmt"
	"time"
)

func main() {
	var ch1 chan int = make(chan int)
	var ch2 chan int = make(chan int)

	go func() {
		fmt.Println("从通道ch2中读取数据:", <-ch2)
	}()

	go func() {
		ch1 <- 88
	}()

	select {
	case <-time.After(time.Second * 5):
		// do something
		fmt.Println("timeout")
	case val := <-ch1:
		fmt.Println("从通道ch1中读取数据", val)
		//  do something
	case ch2 <- 99:
		// do something
	}
	time.Sleep(time.Second * 2)
}

输出信息有两种情况,一种是:

从通道ch2中读取数据: 99

另一种是:

从通道ch1中读取数据 88

猜你喜欢

转载自blog.csdn.net/hzwy23/article/details/82759536
今日推荐