在Go语言中,switch
语句是一种条件控制结构,用于根据不同的条件执行不同的代码块,它比多个if-else
语句更加清晰和易于管理。它有以下几个特点:
分支逻辑自动结束:当一个case
分支匹配成功后,Go会自动结束switch
语句,不需要显式地使用break
来跳出。
支持多种条件表达式类型:在Go中,switch
的条件表达式不局限于常见的整型或字符型,也可以是字符串等其他类型。
支持多值匹配:一个case
可以同时匹配多个值,这些值使用逗号分隔。
支持无表达式语法:Go语言的switch
也可以不带条件表达式,这种情况下,它等同于switch true
,这样可以用作更复杂的条件判断。
支持fallthrough
关键字强制执行:在Go中,可以使用fallthrough
关键字强制执行下一个case
的代码块,但请小心使用,因为这可能导致代码逻辑不清晰。
1. 基本语法
switch
语句的基本语法如下:
switch expression {
case value1:
// 当expression等于value1时执行这里的代码
case value2:
// 当expression等于value2时执行这里的代码
...
default:
// 当没有匹配的case时执行这里的代码
}
2. 分支逻辑自动结束
package main
import (
"fmt"
)
func main() {
fruit := "apple"
switch fruit {
case "apple":
fmt.Println("This is an apple.")
// 在这里不需要break,Go会自动退出switch
case "banana":
fmt.Println("This is a banana.")
case "orange":
fmt.Println("This is an orange.")
default:
fmt.Println("Unknown fruit.")
}
}
输出结果如下,不需要显式地使用break
来跳出。
This is an apple.
3. 支持多种条件表达式类型
package main
import (
"fmt"
)
func handleType(i interface{}) {
switch v := i.(type) {
case int:
fmt.Printf("The integer is %d\n", v)
case string:
fmt.Printf("The string is %s\n", v)
case float64:
fmt.Printf("The float is %f\n", v)
case bool:
fmt.Printf("The boolean is %t\n", v)
default:
fmt.Println("Unknown type")
}
}
func main() {
handleType(42)
handleType("hello")
handleType(3.14)
handleType(true)
}
输出结果
The integer is 42
The string is hello
The float is 3.140000
The boolean is true
上述逻辑中,
-
handleType
函数接受一个空接口interface{}
类型的参数,这意味着它可以接收任何类型的变量。 -
在
switch
语句中,我们使用.(type)
语法来获取参数的实际类型。 -
对于每一种预期的类型(
int
、string
、float64
、bool
),我们编写了一个相应的case
来处理它。 -
如果传入的类型不在这些
case
中,就会执行default
块,并打印"Unknown type"。
4. 支持多值匹配
package main
import (
"fmt"
)
func main() {
day := "Thursday"
switch day {
case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday":
fmt.Println(day, "is a weekday.")
case "Saturday", "Sunday":
fmt.Println(day, "is a weekend.")
default:
fmt.Println(day, "is not a valid day.")
}
}
输出结果
Thursday is a weekday.
- 在
switch
语句中,为工作日和周末分别设置了不同的case
。 - 如果
day
是"Monday"、“Tuesday”、“Wednesday”、"Thursday"或者"Friday"中的任意一个,它将匹配第一个case
并打印出是工作日。 - 如果
day
是"Saturday"或者"Sunday",则匹配第二个case
并打印出是周末。
5. 支持无表达式语法
无表达式的switch
实际上就是不带条件的switch
语句,它默认的比较对象是true
。这种类型的switch
可以用于替代长串的if-else
语句,使代码更加清晰。
package main
import (
"fmt"
"time"
)
func main() {
hour := time.Now().Hour()
switch {
case hour < 12:
fmt.Println("Good morning!")
case hour < 17:
fmt.Println("Good afternoon!")
default:
fmt.Println("Good evening!")
}
}
输出结果
Good morning!
- 根据当前小时数的不同,
switch
会匹配不同的case
- 如果小时数小于12,打印"Good morning!"
- 如果小时数小于17,打印"Good afternoon!“,其他情况下,打印"Good evening!”
6. 支持fallthrough
关键字强制执行
在Go语言中,fallthrough
关键字用于在switch
语句中强制执行下一个case
块的内容,即使下一个case
的条件并未满足。这是Go语言特有的一个特性,与其他语言中的switch
语句有所不同。
package main
import (
"fmt"
)
func main() {
number := 3
switch number {
case 1:
fmt.Println("One")
case 2:
fmt.Println("Two")
fallthrough
case 3:
fmt.Println("Three")
fallthrough
case 4:
fmt.Println("Four")
case 5:
fmt.Println("Five")
default:
fmt.Println("Unknown Number")
}
}
输出结果
Three
Four
代码逻辑
number
为1时,只打印"One"。- 当
number
为2时,将打印"Two",然后由于fallthrough
,继续执行下一个case
,也就是打印"Three"。 - 当
number
为3时,打印"Three",然后由于fallthrough
,继续执行下一个case
,也就是打印"Four"。 - 当
number
为4或5时,只打印对应的"Four"或"Five"。 - 如果
number
不匹配任何case
,则打印"Unknown Number"。
需要注意的是,fallthrough
不会检查下一个case
的条件是否满足,它会无条件地执行下一个case
的代码块。因此,使用fallthrough
时需要谨慎,以避免逻辑错误。
7. switch 和 select搭配使用
select
语句:select
语句在Go中是与协程(goroutines)和通道(channels)密切相关的一个控制结构。它用于处理多个通道的发送和接收操作。当select
有多个case
时,它会随机选择一个可执行的case
执行。如果没有case
可执行,它将阻塞,直到有case
可执行。以下程序创建了两个通道channel1
和channel2
,使用两个协程向这两个通道发送不同的消息,主函数中的select
语句监听这两个通道的消息,当从任一通道接收到消息时,调用handleMessage
函数,并使用switch
语句来根据通道名称处理消息。
package main
import (
"fmt"
"time"
)
func main() {
// 创建两个通道
channel1 := make(chan string)
channel2 := make(chan string)
// 启动一个协程向channel1发送数据
go func() {
time.Sleep(1 * time.Second)
channel1 <- "Message from Channel 1"
}()
// 启动另一个协程向channel2发送数据
go func() {
time.Sleep(2 * time.Second)
channel2 <- "Message from Channel 2"
}()
// 使用select来监听两个通道
for i := 0; i < 2; i++ {
select {
case msg1 := <-channel1:
handleMessage("Channel1", msg1)
case msg2 := <-channel2:
handleMessage("Channel2", msg2)
}
}
}
// handleMessage 使用switch语句来处理不同通道的消息
func handleMessage(channelName, message string) {
switch channelName {
case "Channel1":
fmt.Println("Received from", channelName, ":", message)
case "Channel2":
fmt.Println("Received from", channelName, ":", message)
default:
fmt.Println("Unknown channel")
}
}
输出结果
Received from Channel1 : Message from Channel 1
Received from Channel2 : Message from Channel 2
欢迎来公账号交流,共同学习,共同进步!