结构:
switch express {
case exp1:
todo1
case exp2:
todo2
default:
}
Q1: default定义在最前面和最后面有什么区别?
default的执行时机和default所在的位置无关。不管default是放在所有其他case的前面还是后面,都是先检查其他case,其他case都不满足时,default才会得到执行。
default放在最前面:
func main(){
v := 10
switch v {
default:
fmt.Println("111")
case 10:
fmt.Println("222")
case 20:
fmt.Println("333")
}
}
default放在最后面:
func main(){
v := 10
switch v {
case 10:
fmt.Println("222")
case 20:
fmt.Println("333")
default:
fmt.Println("111")
}
}
上面两种情况的运行结果一致,都是输出:222
Q2: 如果express 同时满足case1和case2的条件,case1在前面,case2在后面,那是case1和case2会先后都执行?
请看示例1:
func main() {
v := 1
switch {
case v < 3:
fmt.Println("222")
case v < 6:
fmt.Println("333")
}
}
运行结果输出一行222就执行结束。
再看示例2:
func main() {
v := 1
switch {
case v < 6:
fmt.Println("333")
case v < 3:
fmt.Println("222")
}
}
运行结果输出一行333就执行结束。
可以看到,switch是从最上面从上到下检查哪个case满足条件,只要某个case满足条件,就执行该case条件分支的逻辑,然后跳出switch case结构,后面的case不管满不满足条件,都不会得到执行。
Q3: switch结构中定义的case1,case2等都和express不匹配时,会循环等待吗
不会循环等待,如果所有case都不满足,也没有default,则什么都不执行就退出。
func main(){
v := 30
switch v {
case 10:
fmt.Println("222")
case 20:
fmt.Println("333")
}
fmt.Println(v)
}
运行结果直接输出30,说明所有case都不满足条件时,switch也不会循环,只执行一次就退出。
Q4: 当express中使用的变量在变化,我们要一直等到v满足某个条件时,怎么做
使用for+switch组合。在switch组合外面包一层for来实现循环执行,当循环到某一次刚好满足某个条件case n时,执行case n中的逻辑,然后别忘了用break来退出for循环。
func main() {
v := 1
go incre(&v)
for {
switch v {
case 10:
fmt.Println("222")
break
case 20:
fmt.Println("333")
}
time.Sleep(1 * time.Second)
}
}
func incre(v *int) {
for i := 0; i < 20; i++ {
time.Sleep(3 * time.Second)
*v += 1
}
}
运行结果:
[work@ hello2]#go run 1.go
222
222
222
333
333
333
运行10s后开始输出3个222(v增加到10),再过10s后,开始输出3个333(v增加到20)。说明switch里面额break并没有break for循环。为什么??有些资料说for switch里面的break是终止switch循环,但是switch本身是没有循环的,需要借助for来实现循环。那switch里面的break有什么作用???
Q5: 接着上面Q4,我们发现switch里面的break好像一点作用都没有。那当在for+switch结构中,某次for循环后满足某个case条件,执行一次case里面的逻辑后我们想退出for循环怎么办?
我们可以用break + name来指定break什么循环:
package main
import (
"fmt"
"time"
)
func main() {
v := 1
go incre(&v)
OPFOR: for {
switch {
case v < 3:
fmt.Println("222")
break OPFOR
case v < 6:
fmt.Println("333")
}
time.Sleep(1 * time.Second)
}
}
func incre(v *int) {
for i := 0; i < 20; i++ {
time.Sleep(2 * time.Second)
*v += 1
}
}
可以看到我们使用了break OPFOR来终止for循环。
Q6: 我们看到switch 后面可以带变量,表达式,也可以什么都不带,有什么区别?
分两种情况,
- 如果switch后面什么都不带,则每个case分支的表达式结果只要是boolena类型就可以
- 如果switch后面带了某个变量,比如int类型的,则每个case分支的表达式结果必须跟这个变量的类型保持一致,这样switch case才能对条件做校验比较
总结起来就是:落脚到每个case 语句都是boolean类型,true或者false
示例1:
func main() {
v := 1
switch {
case v < 3:
fmt.Println("222")
case v < 6:
fmt.Println("333")
}
}
输出222
示例2:
func main() {
v := 1
switch v{
case 1:
fmt.Println("222")
case 2:
fmt.Println("333")
}
}
输出222
示例3:
import (
"fmt"
"time"
)
func main() {
v := 1
switch v {
case v < 3:
fmt.Println("222")
case v < 6:
fmt.Println("333")
}
}
运行结果:
[work@ hello2]#go run 1.go
# command-line-arguments
./1.go:5:2: imported and not used: "time"
./1.go:11:2: invalid case v < 3 in switch on v (mismatched types bool and int)
./1.go:13:2: invalid case v < 6 in switch on v (mismatched types bool and int)
[work@ hello2]#
总结
- 1)default定义在其他case的前面或者后面没有任何影响。
- 2)如果case1和case2都满足条件,谁排在前面执行谁
- 3)没有default时,如果所有case都不满足条件,则switch case直接跳出,什么都不执行。即switch case结构本身没有循环执行能力。
- 4)可以使用for+switch结构来让switch循环执行,但是switch里面的break没有任何意义。可以用break+循环名称来指定break哪种循环结构
- 5)switch后面可以不带表达式,也可以带表达式(或者变量),对应的case 表达式也不一样,但是落脚到case最终的结构,只有true或者false两种情况。
有疑问加站长微信联系(非本文作者)