go语言switch/select中表达式求值顺序

switch/select语句中表达式的求值属于惰性求值,在需要进行求值时才会对表达式进行求值。这样

做的目的是降低程序消耗,对性能提升有一定的帮助。

package main

import "fmt"

func expr(n int) int {
	fmt.Println(n)
	return n
}

func main() {
	switch expr(2) {
	case expr(1), expr(2), expr(3):
		fmt.Println("This is case1")
		fallthrough
	case expr(4):
		fmt.Println("This is case2")
	}
}

运行程序结果:

go run .\evaluation_order.go
2
1
2
This is case1
This is case2

对于switch- case语句而言,首先进行求值的是switch后边的表达式expr(2),这个表达式求值时输出2

接下来按照从上到下、从左到右的顺序对case语句中的表达式进行求值。如果某个表达式的结果与switch表达式的结果一致,那么停止求值。expr(3)求值被忽略。

fallthrough直接跳到下一个case执行语句中,忽略了case表达式expr(4)的求值。

go语言中的select为我们提供了一种在多个channel间实现“多路复用”的机制,时编写go语言并发程

序最常用的并发原语之一。select-case语句中表达式求值顺序:

package main

import (
	"fmt"
	"time"
)

func getAReadOnlyChannel() <-chan int {
	fmt.Println("This is getAReadOnlyChannel")
	c := make(chan int)

	go func() {
		time.Sleep(5 * time.Second)
		c <- 1
	}()
	return c
}

func getASlice() *[5]int {
	fmt.Println("This is getASlice")
	var s [5]int
	return &s
}

func getAWriteOnlyChannel() chan<- int {
	fmt.Println("This is getAWriteOnlyChannel")
	return make(chan int)
}

func getANumToChannel() int {
	fmt.Println("This is getANumToChannel")
	return 2
}

func main() {
	select {
	// 从channel接收数据
	case (getASlice())[0] = <-getAReadOnlyChannel():
		fmt.Println("receive something from a readonly channel")
	// 将数据发送到channel
	case getAWriteOnlyChannel() <- getANumToChannel():
		fmt.Println("send something to a write only channel")
	}
}

执行结果:

go run .\evaluation_order.go
This is getAReadOnlyChannel
This is getAWriteOnlyChannel
This is getANumToChannel

This is getASlice
receive something from a readonly channel

①select执行开始时,首先所有的case表达式都会被按出现的先后顺序求值一遍。但是,位于case等号左边的从channel接收数据的表达式不会被求值。即getASlice()不会被执行。

②如果选择要执行的是一个从channel接收数据case,那么该case等号左边的表达式在接收前才会被求值。该例中,在getAReadOnlyChannel创建的goroutine在5s后向channel中写入一个int值后,输出“This is getASlice”。这也是一种惰性求值。

Go语言基础及实战 文章被收录于专栏

Go语言学习笔记、语法知识、技术要点和个人理解及实战

全部评论

相关推荐

我是小红是我:学校换成中南
点赞 评论 收藏
分享
斑驳不同:还为啥暴躁 假的不骂你骂谁啊
点赞 评论 收藏
分享
评论
点赞
1
分享
牛客网
牛客企业服务