开发者学堂课程【Go语言核心编程 - 基础语法、数组、切片、Map:switch使用细节(1)】与课程紧密联系,让用户快速学习知识
课程地址:https://developer.aliyun.com/learning/course/625/detail/9570
switch使用细节(1)
一、switch使用注意事项和细节讨论
对于与switch细节讨论总结了10点,下面进行具体讨论。
1、特性一
case 后是一个表达式(即:常量值、变量、一个有返回值的函数等都可以);
案例:
var
key byte
…
fmt.Scanf(“%c”,&key)
switch ‘a’{
//可以将key变量改为a。
case ‘a’:
fmt.Println(“周一,猴子穿新衣”)
case ‘b’:
fmt.Println(“周二,猴子当小二”)
case ‘c’:
fmt.Println(“周三,猴子爬雪山”)
//…
default:
Fmt.Println(“输入有误
…
”)
}
}
如上可以将 key 变量改为a,就意味着固定表达式的值为a,会永远匹配为周一,猴子穿新衣,这样从语法上是支持的,所以下面进行运行,如果输入为g,这个时候代码却并没有拿g进行匹配而是直接写的a,所以会输出猴子穿新衣。
运行结果:D:\goproject\src\go_code\chapter05\switchdemo\demo01>go run main.go
请输入一个字符a,b,c,d,e,f,g
g
周一,猴子穿新衣
说明直接写常量是可以的,甚至是一个有返回的函数也是可以的,比如写一个简单的函数 test,返回一个简单的值byte,代码为:
func
test(
b byte)byte{
return
b+
1
//意思是传入b进来, byte+1再进行返回去。
}
…
switch t
est
(
key)
{
//test传入变量key,
case ‘a’:
fmt.Println(“周一,猴子穿新衣”)
case ‘b’:
fmt.Println(“周二,猴子当小二”)
case ‘c’:
fmt.Println(“周三,猴子爬雪山”)
//…
default:
Fmt.Println(“输入有误
…
”)
}
运行结果:D:\goproject\src\go_code\chapter05\switchdemo\demo01>go run main.go
请输入一个字符a,b,c,d,e,f,g
a
周二,猴子当小二
发现以上输入a时返回为周二,猴子当小二,是因为输入a后函数给a加上1,a+1后对应的asc码字符为b,所以就匹配到了b的语句块。通过这个案例强调的是语句中表达式也可以是函数,甚至可以对表达式进行运算,如在test(key)后再加上1,代码为:
switch t
est
(
key)+1
{
//这里主要讲的语法现象
case ‘a’:
fmt.Println(“周一,猴子穿新衣”)
case ‘b’:
fmt.Println(“周二,猴子当小二”)
case ‘c’:
fmt.Println(“周三,猴子爬雪山”)
//…
default:
Fmt.Println(“输入有误
…
”)
}
运行结果:D:\goproject\src\go_code\chapter05\switchdemo\demo01>go run main.go
请输入一个字符a,b,c,d,e,f,g
a
周三,猴子爬雪山D:\goproject\src\go_code\chapter05\switchdemo\demo01>go run main.go
请输入一个字符a,b,c,d,e,f,g
b
输入有误…
如上输入a,a进行加1再加1,匹配到c的asc码值则输出周三,猴子爬雪山,输入b时,b进行加1再加1,匹配到d的asc码值,匹配不上,则输出输入有误…。以上的案例强调的是表达式只要有一个值就行,不管是函数返回的还是预算得到的都可以,switch后可以这样写case后也可以写成函数或者变量。
2、特性二
case后的各个表达式的值的数据类型,必须和 switch 的表达式数据类型一致。
案例:
var n1 int32 = 20
var n2 int
32
=20
//定义两个变量n1,n1,都类型为int32,赋值为20。
switch n1{
case n2:
//错误,原因是n2的数据类型和n1不一致
fmt.Println(“ok1”)
default:
fmt.Println(“没有匹配到”)
}
运行结果:D:\goproject\src\go_code\chapter05\switchdemo\demo01>go run main.go
ok
1
此时运行程序匹配成功输出ok1,但是如果修改代码为:
var n1 int32 = 20
var n2 int
64
=20
case n2:语句会出现提示报错,提示为 int64和 int32无效匹配,因此得出 switch 表达式数据类型要和case表达式数据类型保持一致,否则会报错,那如果把 case n1改为 case 20是可以的,因为是一个具体的值了,20是一个具体的数,他本身并不带数据类型,就相当于把20赋值给n1也是可以的,改为n2不行是因为n2不能直接赋值给n1,n1和n2的数据类型不一样,但是一个具体的值是可以的,因为具体的值并没有包含数据类型在里面,所以这里需要注意数据类型保持一致,否则会报错。
3、特性三
Case 后面可以带多个表达式,使用逗号间隔。比如 case 表达式1,表达式2...;
案例:
var n1 int32 =
5
var n2 int32 =20
switch n1{
case n2,10,5:
//case后面可以有多个表达式,可以为函数也可以为数值
fmt.Println(“ok1”)
default:
fmt.Println(“没有匹配到”)
}
将程序修改为var n1 int32 =
5
,则n1与case后表达式5进行匹配输出ok1。
运行结果:D:\goproject\src\go_code\chapter05\switchdemo\demo01>go run main.go
ok
1
4、特性四
case 后面的表达式如果是常量值(字面量),则要求不能重复
案例:
如果代码中前面有一个常量5,后面再进行case 5:则会报错,报错提示为case 5重复了,在前面已经定义过,所以重复定义语法上是不支持的,代码为:
var n1 int32 =
5
var n2 int64 =20
switch n1{
case n2:
fmt.Println(
“
ok1
”
case 5:
//错误,因为前面有常量5,因此重复,就会报错(是变量就不会报错)
fmt.Println(
“
ok2
”)
default:
fmt.Println(
“
没有匹配到
”
)
}
但是变量就不会报错,比如再定义一个int32类型的变量n3,赋值为5。所以如果Case 后面的表达式不是常量值,编译器识别不出来认为是变量就不会报错,代码为:
var n1 int32 =
5
var n2 int64 =20
switch n1{
case n2:
fmt.Println(
“
ok1
”
)
case n
3:
//不会报错,编译器识别不出来
fmt.Println(
“
ok2
”)
default
fmt.Println(
“
没有匹配到
”)
}
5、特性五
case 后面不需要带 break ,程序匹配到一个 case 后就会执行对应的代码块,然后退出 switch ,如果一个都匹配不到,则执行 default;
前面已经讲过,这里不再细说。
6、特性六
default 语句不是必须的。
案例:
如下面案例不写default 语句也是可以的,n1等于51与case1语句和case2语句都不匹配,而后面也没有default,那就什么都不输出就可以。
代码为:
var n1 int32 = 51
var n2 int32 =20
switch n1{
case n2,10,5:
//case 后面可以有多个表达式
fmt.Println(
“
ok1
”
)
case 90:
fmt.Println(
“
ok2
”
)
}
运行结果:D:\goproject\src\go_code\chapter05\switchdemo\demo01>go run main.go
D:\goproject\src\go_code\chapter05\switchdemo\demo01>
运行结果什么都没有输出,说明 default 语句可以有也可以没有。