Derick
693 words
3 minutes
Go语言教程:深入解析通道和选择语句 3

本文将通过一段代码示例,详细讲解Go语言中的通道(Channel)和选择语句(Select)的使用。我们将逐步解析代码中的每个部分,帮助你更好地理解这些概念。

示例代码#

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	example1()
	example2()
}

// 示例1。
func example1() {
	// 准备好几个通道。
	intChannels := [3]chan int{
		make(chan int, 1),
		make(chan int, 1),
		make(chan int, 1),
	}
	// 随机选择一个通道,并向它发送元素值。
	index := rand.Intn(3)
	fmt.Printf("The index: %d\\n", index)
	intChannels[index] <- index
	// 哪一个通道中有可取的元素值,哪个对应的分支就会被执行。
	select {
	case <-intChannels[0]:
		fmt.Println("The first candidate case is selected.")
	case <-intChannels[1]:
		fmt.Println("The second candidate case is selected.")
	case elem := <-intChannels[2]:
		fmt.Printf("The third candidate case is selected, the element is %d.\\n", elem)
	default:
		fmt.Println("No candidate case is selected!")
	}
}

// 示例2。
func example2() {
	intChan := make(chan int, 1)
	// 一秒后关闭通道。
	time.AfterFunc(time.Second, func() {
		close(intChan)
	})
	select {
	case _, ok := <-intChan:
		if !ok {
			fmt.Println("The candidate case is closed.")
			break
		}
		fmt.Println("The candidate case is selected.")
	}
}

示例1:使用 select 语句选择通道#

代码解析#

example1 函数中,我们创建了一个包含三个通道的数组 intChannels。每个通道都是带缓冲的,缓冲区大小为1。

intChannels := [3]chan int{
	make(chan int, 1),
	make(chan int, 1),
	make(chan int, 1),
}

接下来,我们随机选择一个通道,并向该通道发送一个元素值。

index := rand.Intn(3)
fmt.Printf("The index: %d\\n", index)
intChannels[index] <- index

然后,我们使用 select 语句来选择哪个通道中有可取的元素值。select 语句会随机选择一个可用的通道进行操作。

select {
case <-intChannels[0]:
	fmt.Println("The first candidate case is selected.")
case <-intChannels[1]:
	fmt.Println("The second candidate case is selected.")
case elem := <-intChannels[2]:
	fmt.Printf("The third candidate case is selected, the element is %d.\\n", elem)
default:
	fmt.Println("No candidate case is selected!")
}

运行结果#

运行结果会根据随机选择的通道不同而有所变化。例如:

The index: 1
The second candidate case is selected.

示例2:通道关闭检测#

代码解析#

example2 函数中,我们创建了一个带缓冲的通道 intChan,缓冲区大小为1。

intChan := make(chan int, 1)

我们使用 time.AfterFunc 函数在一秒后关闭该通道。

time.AfterFunc(time.Second, func() {
	close(intChan)
})

接下来,我们使用 select 语句来检测通道是否关闭。

select {
case _, ok := <-intChan:
	if !ok {
		fmt.Println("The candidate case is closed.")
		break
	}
	fmt.Println("The candidate case is selected.")
}

运行结果#

由于通道在一秒后关闭,运行结果将会是:

The candidate case is closed.

总结#

通过这两个示例,我们学习了如何使用Go语言中的通道和选择语句。通道用于在不同的Go协程之间传递数据,而选择语句则用于在多个通道操作中进行选择。希望通过本文的讲解,你能更好地理解和应用这些概念。

Go语言教程:深入解析通道和选择语句 3
https://blog.ithuo.net/posts/go-channel-tutorial-3/
Author
Derick
Published at
2022-05-08