Golang switch statement and select statement usage tutorial

  • 2020-06-03 06:55:18
  • OfStack

This article mainly introduces the usage of switch and select in Golang and shares it for your reference and study. Let's start with 1 to see the detailed introduction:

1. switch statements

The switch statement provides a method for executing multiple branch conditions. Each case can carry 1 expression or 1 type descriptor. The former, in turn, can be referred to simply as the case expression. Therefore, switch statements of Go language are divided into expression switch statement and type switch statement.

1. Expression switch statement


var name string 
... 
switch name { 
case "Golang": 
 fmt.Println("Golang") 
case "Rust": 
 fmt.Println("Rust") 
default: 
 fmt.Println("PHP It's the best language in the world ") 
} 

Go evaluates the case expression in each case statement from top to bottom, and the case expression is selected whenever it is found to have the same result as the switch expression. The remaining case statements are ignored. As with if, the switch statement can also contain an initializer sentence, with its position and writing as follows:


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

2. Type switch statement

The type switch statement differs from the 1 common form in two ways. First, the case keyword is followed not by an expression, but by a type specifier. A type descriptor consists of several type literals separated by English commas. Second, its switch expression is very special. This particular expression also ACTS as a type assertion, but in a special form, such as: v.(type) , where v must represent the value of 1 interface type. This type of expression can only appear in type switch statements and can only act as an switch expression. An example of a type switch statement is as follows:


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

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

And finally fallthrough 1. It is both a keyword and a statement. The fallthrough statement can be included in the case statement in the expression switch statement. Its function is to transfer control to the next case. Note, however, that the fallthrough statement can only appear as the last statement in case. Also, the case statement containing it is not the last case statement to which it belongs.

2. select statements

The function of select of golang is similar to that of select, poll and epoll. It is to monitor IO operation and trigger corresponding action when IO operation occurs.

Example:


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

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

In this example, select 1 waits until some case statement is completed, that is, until the data is successfully read from ch1 or ch2. The select statement ends.

The break statement can also be included in the case statement within the select statement. It is used to immediately end the execution of the current select statement. Whether or not there is an unexecuted statement in the case statement to which it belongs.

[Using select to implement timeout mechanism]

As follows:


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

When the timeout expires, case2 succeeds. So the select statement exits. Instead of 1 blocking directly on ch's read operation. Thus, the timeout setting for ch read operation is achieved.

The next one is a little bit more interesting.

When the select statement has default:


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

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

Because of this default feature, we can use the select statement to check if chan is full.

As follows:


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

Since ch is full when inserting 1, when ch wants to insert 2, ch is full (case1 is blocked), then select executes the default statement. This makes it possible to detect if channel is full, rather than waiting for 1.

For example, if we have a service, when a request comes in, we will generate an job and throw it into channel. Other coroutines will get job from channel to execute. But we hope that when channel has been cheated, it will be abandoned and replied [Service is busy, please try again a little bit.] You can implement this requirement with select.

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


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

conclusion


Related articles: