• 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
  • 相关阅读:
    关掉firefox(火狐)和palemoon地址栏自动加www.前缀功能【转】
    Maven入门指南(一)
    Linux 常用命令
    maven-编译速度优化
    monkeyscript
    GIT
    maven简介及基础使用
    使用xcrun打包iOS应用
    Mac系统下STF的环境搭建和运行
    npm介绍与cnpm介绍
  • 原文地址:https://www.cnblogs.com/levin-ling/p/13276369.html
Copyright © 2020-2023  润新知