golang-switch结构辨析有话
Posted levin-ling
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang-switch结构辨析有话相关的知识,希望对你有一定的参考价值。
此文基于switch的注意事项而发,其中某些情况可能并不常见,但还是小心为好,能够帮助我们精简代码(编译环境:cmder)
匹配项不精准
①某些case可能永远匹配不到,造成浪费
package main import "fmt" func test(char byte) byte { return char+1 } func main() { var key byte fmt.Println("请输入一个字符") fmt.Scanf("%c",&key) switch test(key) { case ‘a‘: fmt.Println("a") case ‘b‘: fmt.Println("b") case test(key)+1: fmt.Println("c") case ‘d‘,‘e‘: fmt.Println("de") default: fmt.Println("输入错误") } } λ go run main.go 请输入一个字符 a a λ go run main.go 请输入一个字符 b 输入错误 # 显然,再往下输入已经没有意义,case test(key)+1:的情况始终都匹配不到
②其中一项case可能成为default,然而真正的default会失去地位
package main import "fmt" func test(char byte) byte { return char+1 } func main() { var key byte fmt.Println("请输入一个字符") fmt.Scanf("%c",&key) switch test(key) { case ‘a‘: fmt.Println("a") case ‘b‘: fmt.Println("b") case test(key): fmt.Println("c") case ‘d‘,‘e‘: fmt.Println("de") default: fmt.Println("输入错误") } } # 这里只要输入的不是a,b,d,e,最终输出结果都是 “c”,不会输出 “输入错误”
数据类型匹配问题
①数据类型相同,值相同
package main import "fmt" func main() { var n1 int32 = 20 var n2 int32 = 20 switch n1 { case n2: fmt.Println("ok1") default: fmt.Println("没有匹配到") } } λ go run main.go ok1
②数据类型不同,值相同
package main import "fmt" func main() { var n1 int32 = 20 var n2 int64 = 20 switch n1 { case n2: fmt.Println("ok1") default: fmt.Println("没有匹配到") } } λ go run main.go # command-line-arguments .main.go:8:3: invalid case n2 in switch on n1 (mismatched types int64 and int32)
③数据类型不同,case表达式从变量替换为常量,但常量与变量的值相同
package main import "fmt" func main() { var n1 int32 = 20 // var n2 int64 = 20 switch n1 { case 20: fmt.Println("ok1") default: fmt.Println("没有匹配到") } } λ go run main.go ok1
④采用默认数据类型进行匹配
package main import "fmt" func main() { var n1 int32 = 20 var n2 = 20 switch n1 { case n2: fmt.Println("ok1") default: fmt.Println("没有匹配到") } } λ go run main.go # command-line-arguments .main.go:8:3: invalid case n2 in switch on n1 (mismatched types int and int32)
参考③可以理解为,将20赋值给n1;因此①②可以理解为将n2赋值给n1,必然要求值和类型都必须相等;④因为按照类型推导模式,整数类型默认为int,不是int8,更不是int32,千万不能忽视
case表达式出现重复值
①格式相同
package main import "fmt" func main() { var n1 int32 = 5 var n2 int32 = 20 var n3 int32 = 5 switch n1 { case n2, 10, 5: fmt.Println("ok1") case 5: fmt.Println("ok2") default: fmt.Println("没有匹配到") } } λ go run main.go # command-line-arguments .main.go:12:8: duplicate case 5 in switch previous case at .main.go:10:16
# 显然,不可能出现两个相同的常量匹配项
②不是编译器能直接识别的相同值
package main import "fmt" func main() { var n1 int32 = 5 var n2 int32 = 20 var n3 int32 = 5 switch n1 { case n2, 10, 5: fmt.Println("ok1") case n3: fmt.Println("ok2") default: fmt.Println("没有匹配到") } } λ go run main.go ok1 # 因为编译器不是足够智能,变量不能被直接识别出相应的值,故不会报错,同时也说明一个case支持多个表达式
default非必须性
package main import "fmt" func main() { var n1 int32 = 51 var n2 int32 = 20 switch n1{ case n2, 10 ,5: fmt.Println("ok1") case 90: fmt.Println("ok2") } } λ go run main.go # 没有输出结果,即使没有对应值,不写default的情况也不会报错,只是没有输出值而已
可替代if-else结构
func main() { var age int = 10 switch { case age == 20: fmt.Println("age=20") case age == 10: fmt.Println("age=10") default: fmt.Println("没有匹配到") } } # 这种情况下switch后面不用写任何表达式,相当于一个作用域
package main import "fmt" func main() { var score int = 30 switch { case score > 90: fmt.Println("成绩优秀") case score >= 70 && score < 90: fmt.Println("成绩优良") case score >=60 && score < 70: fmt.Println("成绩及格") default: fmt.Println("成绩不及格") } } # case的表达式可以对范围进行判断,此时完全相当于if-else
用switch直接定义变量
package main import "fmt" func main() { switch grade := 90;{ case grade > 90: fmt.Println("成绩优秀") case grade >= 70 && grade <= 90: fmt.Println("成绩优良") case grade >= 60 && grade < 70: fmt.Println("不及格") } } # 注意,定义完变量后面有分号
switch穿透延伸
package main import "fmt" func main() { var num int = 10 switch num { case 10: fmt.Println("ok1") fallthrough case 20: fmt.Println("ok2") case 30: fmt.Println("ok3") default: fmt.Println("没有匹配到") } }
λ go run main.go
ok1
ok2
# 不建议switch穿透,因为如果要执行两个case,直接写在一个case里面就行
package main import "fmt" func main() { var num int = 10 switch num { case 10: fmt.Println("ok1") fallthrough case 20: fmt.Println("ok2") fallthrough case 30: fmt.Println("ok3") fallthrough default: fmt.Println("没有匹配到") } } λ go run main.go ok1 ok2 ok3 没有匹配到 # 可全部穿透,包括default
以上是关于golang-switch结构辨析有话的主要内容,如果未能解决你的问题,请参考以下文章