SoFunction
Updated on 2025-03-02

Tutorial on how to use switch statements and select statements in Golang

This article mainly introduces relevant content on the usage of switch and select in Golang. We will share it for your reference and learning. Let’s take a look at the detailed introduction together:

1. Switch statement

The switch statement provides a method for multi-branch conditional execution. Each case can carry an expression or a type specifier. The former can also be referred to as a case expression. Therefore, the switch statements in Go language are divided into expression switch statements and type switch statements.

1. Expression switch statement

var name string 
... 
switch name { 
case "Golang": 
 ("Golang") 
case "Rust": 
 ("Rust") 
default: 
 ("PHP is the best language in the world") 
} 

Go will evaluate the case expression in each case statement in order from top to bottom. As long as it is found that its expression is the same as the switch expression, the case statement will be selected. The remaining case statements will be ignored. Like if, the switch statement can also contain initialization sentences, and its appearance location and writing method are exactly the same:

names := []string{"Golang","java","PHP"} 
switch name:=names[0];name { 
case "Golang": 
 ("Golang") 
... 
default: 
 ("Unknown") 
} 

2. Type switch statement

There are two differences between type switch statements and general forms. The first point is that the case keyword is not an expression, but a type specifier. A type specifier consists of several type literals, and the multiple type literals are separated by English commas. The second point is that its switch expression is very special. This special expression also plays the role of type assertion, but its expression is very special, such as:v.(type), where v must represent a value of an interface type. This class expression can only appear in type switch statements and can only act as switch expressions. An example of a type switch statement is as follows:

v := 11 
switch i := interface{}(v).(type) { 
case int, int8, int16, int32, int64: 
 ("A signed integer:%d. The type is %T. \n", v, i) 
case uint, uint8, uint16, uint32, uint64: 
 ("A unsigned integer: %d. The type is %T. \n", v, i) 
default: 
 ("Unknown!") 
} 

Here we assign the result of the switch expression to a variable. In this way, we can use this result in this switch statement. After this code is executed, the output is:"A signed integer:11. The type is int. "

Finally, let’s talk about fallthrough. It is both a keyword and can represent a statement. The fallthrough statement may be included in the case statement in the expression switch statement. Its purpose is to flow control to the next case. However, it should be noted that the fallthrough statement can only appear as the last statement in the case statement. And, the case statement containing it is not the last case statement of the switch statement to which it belongs.

2. Select statement

The function of golang's select is similar to select, poll, and epoll, which is to listen for IO operations and trigger the corresponding action when the IO operation occurs.

Example:

ch1 := make (chan int, 1) 
ch2 := make (chan int, 1) 
 
... 
 
select { 
case <-ch1: 
 ("ch1 pop one element") 
case <-ch2: 
 ("ch2 pop one element") 
} 

Note that the code form of select is very similar to switch, but the operation statement in the case of select can only be [IO operation].

In this example, select will wait until a case statement completes, that is, it will successfully read data from ch1 or ch2. Then the select statement ends.

The break statement can also be included in the case statement in the select statement. Its function is to immediately end the execution of the current select statement. Regardless of whether there are any unexecuted statements in the case statement to which it belongs.

【Use select to implement timeout mechanism】

as follows:

timeout := make(chan bool, 1) 
go func() { 
 ( * 10) 
 timeout <- true 
}() 
select { 
case <-pssScanResponseChan: 
 
case <-timeout: 
 ("timeout!") 
} 

When the timeout time is up, case2 will operate successfully. Therefore, the select statement will exit. Instead of blocking the read operation of ch. This implements the timeout setting for the ch read operation.

The following is more interesting.

When the select statement has default:

ch1 := make (chan int, 1) 
ch2 := make (chan int, 1) 
 
select { 
case <-ch1: 
 ("ch1 pop one element") 
case <-ch2: 
 ("ch2 pop one element") 
default: 
 ("default") 
} 

At this time, because ch1 and ch2 are both empty, neither case1 nor case2 will be read successfully. Then select executes the default statement.

It is because of this default feature that we can use the select statement to detect whether chan is full.

as follows:

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

Because ch is already full when inserting 1, when ch is about to insert 2, it is found that ch is already full (case1 blocks), select executes the default statement. This allows you to detect whether the channel is full, rather than waiting all the time.

For example, we have a service. When the request comes in, we will generate a job and throw it into the channel, and other coroutines will obtain the job from the channel to execute. But we hope that when the channel is hidden, we will abandon the job and reply [The service is busy, please try again. 】 You can use select to achieve this requirement.

In addition, using the default feature, we can use the select statement to clear the chan, as follows:

flag := false 
for { 
 select { 
 case <-pssScanResponseChan: 
 continue 
 default: 
 flag = true 
 } 
 if true == flag { 
 break 
 } 
} 

Summarize

The above is the entire content of this article. I hope the content of this article will be of some help to your study or work. If you have any questions, you can leave a message to communicate. Thank you for your support.