go学习笔记(18)switch

22-07-01 18-03-01 4565.jpg

在c/c++中switch只能处理整型或枚举,而且忘记写break的话会执行下一个case中的语句,容易出错。 go语言中的switch相比c/c++要强大很多,非常好用。

支持任意类型

go语言switch处理的变量可以是任意支持用==进行判断的类型。我现在最常用的就是对字符串用switch判断,匹配到相应的值就进入对应的分支。

1
2
3
4
5
6
7
8
9
10
11
12
var command string
fmt.Scanf("%s", &command)
switch command {
case "version":
fmt.Println("v 1.0.0")
case "haha":
fmt.Println("hehe")
case "你好":
fmt.Println("世界")
default:
fmt.Println("我不理解")
}

输出:

1
2
3
4
5
6
7
8
9
10
11
// 输入"version"
v 1.0.0

// 输入"haha"
hehe

// 输入"你好"
世界

// 输入"晚饭吃什么"
我不理解

是不是很好用,而且注意上面的这段代码中在语句的末尾没有break,go语言中的switch在当前case执行完后默认不执行后面的case直接返回,相当于每个case默认都有一个break

多case合并执行

如果我想实现类似c/c++中的多个case执行相同的代码怎么做呢,有两种方案,一种是多个条件写在一起用逗号分开:

1
2
3
4
5
6
7
8
9
10
var input string
fmt.Scanf("%s", &input)
switch input {
case "cat", "dog", "cock", "duck", "fish":
fmt.Println("animal")
case "girl", "boy", "man", "woman":
fmt.Println("human")
case "rose", "jasmine", "orchid":
fmt.Println("flower")
}

输出:

1
2
3
4
5
6
7
8
9
10
11
// 输入"cat"
animal

// 输入"dog"
animal

// 输入"boy"
human

// 输入"orchid"
flower

另一种方式是通过fallthrough关键字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var input string
fmt.Scanf("%s", &input)
switch input {
case "cat": fallthrough
case "dog": fallthrough
case "cock": fallthrough
case "duck": fallthrough
case "fish":
fmt.Println("animal")
case "girl": fallthrough
case "boy": fallthrough
case "man": fallthrough
case "woman":
fmt.Println("human")
case "rose": fallthrough
case "jasmine": fallthrough
case "orchid":
fmt.Println("flower")
}

输出:

1
2
3
4
5
6
7
8
// 输入"cock"
animal

// 输入"woman"
human

// 输入"rose"
flower

fallthrough的这种形式太繁琐了,一般没人会这样写。

声明变量

iffor一样switch也支持直接在语句中声明变量:

1
2
3
4
5
6
7
8
9
10
11
12
var input string
fmt.Scanf("%s", &input)
switch l := len(input); l {
case 1:
fmt.Println("长度为1")
case 2:
fmt.Println("长度为2")
case 3:
fmt.Println("长度为3")
default:
fmt.Println("数不过来了")
}

输出:

1
2
3
4
5
6
7
8
// 输入"I"
长度为1

// 输入"love"
数不过来了

// 输入"you"
长度为3

break

一般而言在switch语句中不需要写break,但如果要提前结束case中的语句也可以用break。

如果switchfor一起使用的话,要格外小心。switch中的break默认是结束switch语句的,如果要在switch中结束外层的for则需要用break 标签的写法。

直接写break只能退出switch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for i := 0; i < 5; i++ {
switch i {
case 0:
fmt.Println("零")
case 1:
fmt.Println("壹")
case 2:
fmt.Println("贰")
break
case 3:
fmt.Println("叁")
case 4:
fmt.Println("肆")
}
}

输出:

1
2
3
4
5





通过break 标签来退出循环:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
EXIT:
for i := 0; i < 5; i++ {
switch i {
case 0:
fmt.Println("零")
case 1:
fmt.Println("壹")
case 2:
fmt.Println("贰")
break EXIT
case 3:
fmt.Println("叁")
case 4:
fmt.Println("肆")
}
}

输出:

1
2
3



空白switch语句

switch语句可以为空!普通的switch语句中我们只能执行是否相等的判断。空白switch语句支持对每个case进行任意的布尔运算进行比较。

1
2
3
4
5
6
7
8
9
10
var x int
fmt.Scanf("%v", &x)
switch {
case x > 10:
fmt.Println("x>10")
case x < 10:
fmt.Println("x<10")
case x == 10:
fmt.Println("x=10")
}

输出:

1
2
3
4
5
6
7
8
// 输入"5"
x<10

// 输入"10"
x=10

// 输入"30"
x>10

这个特性真的很方便,相当于把一大坨if else合在了一起,很简洁直观。当我们要比较的数据的多个case相互之间有关联时最适合采用这种写法了。

江达小记