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语法格式

select {
    case communication clause  :
       statement(s);      
    case communication clause  :
       statement(s);
    /* 你可以定义任意数量的 case */
    default : /* 可选 */
       statement(s);
}

示例

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

func main() {
	ch1 := make(chan int)
	ch2 := make(chan string)

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

	go func() {
		num2 := <-ch2
		fmt.Println(num2)
	}()

	select {
	case num1 := <-ch1: //读取channel数据
		fmt.Println("ch1中的数据是:", num1)
	case ch2 <- "201": //channel写入数据
		fmt.Println("ch2有数据写入")
	}
}

 

随机性

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

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

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

	go func() {
		ch1 <- 100
	}()
	go func() {
		ch2 <- 200
	}()

	select {
	case num1 := <-ch1:
		fmt.Println("ch1中的数据是:", num1)
	case num2 := <-ch2:
		fmt.Println("ch2中的数据是:", num2)
	}
}

 

死锁

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

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

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

 

default语句

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

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

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

	select {
	case num1 := <-ch1:
		fmt.Println("ch1中的数据是:", num1)
	case num2 := <-ch2:
		fmt.Println("ch2中的数据是:", num2)
	default:
		fmt.Println("通道阻塞...default")
	}
}

 

超时语句

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

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

	select {
	case num1 := <-ch1:
		fmt.Println("ch1中的数据是:", num1)
	case num2 := <-ch2:
		fmt.Println("ch2中的数据是:", num2)
	case <-time.After(3 * time.Second):
		fmt.Println("timeout...")
	}
}

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值