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结构辨析有话的主要内容,如果未能解决你的问题,请参考以下文章

指针辨析:悬垂指针哑指针野指针智能指针

针对Sybase数据库无法启动的情况,我有话要说

辨析 roleimport_roleinclude_role

VSCode自定义代码片段5——HTML元素结构

VSCode自定义代码片段5——HTML元素结构

VSCode自定义代码片段5——HTML元素结构