美文网首页
golang switch case结构

golang switch case结构

作者: 舒小贱 | 来源:发表于2020-01-20 23:19 被阅读0次

    结构:

    switch express {
        case exp1:
            todo1
        case exp2:
            todo2
        default:
            
    }
    

    Q1: default定义在最前面和最后面有什么区别?

    default的执行时机和default所在的位置无关。不管default是放在所有其他case的前面还是后面,都是先检查其他case,其他case都不满足时,default才会得到执行。
    default放在最前面:

    func  main(){
        v := 10
        switch v {
            default:
                fmt.Println("111")
            case 10:
                fmt.Println("222")
            case 20:
                fmt.Println("333")
        }
    }
    

    default放在最后面:

    func  main(){
        v := 10
        switch v {
            case 10:
                fmt.Println("222")
            case 20:
                fmt.Println("333")
            default:
                fmt.Println("111")
        }
    }
    

    上面两种情况的运行结果一致,都是输出:222

    Q2: 如果express 同时满足case1和case2的条件,case1在前面,case2在后面,那是case1和case2会先后都执行?

    请看示例1:

    func main() {
        v := 1
        switch {
        case v < 3:
            fmt.Println("222")
        case v < 6:
            fmt.Println("333")
        }
    }
    

    运行结果输出一行222就执行结束。
    再看示例2:

    func main() {
        v := 1
        switch {
        case v < 6:
            fmt.Println("333")
        case v < 3:
            fmt.Println("222")
        }
    }
    

    运行结果输出一行333就执行结束。
    可以看到,switch是从最上面从上到下检查哪个case满足条件,只要某个case满足条件,就执行该case条件分支的逻辑,然后跳出switch case结构,后面的case不管满不满足条件,都不会得到执行。

    Q3: switch结构中定义的case1,case2等都和express不匹配时,会循环等待吗

    不会循环等待,如果所有case都不满足,也没有default,则什么都不执行就退出。

    func  main(){
        v := 30
        switch v {
            case 10:
                fmt.Println("222")
            case 20:
                fmt.Println("333")
        }
        fmt.Println(v)
    }
    

    运行结果直接输出30,说明所有case都不满足条件时,switch也不会循环,只执行一次就退出。

    Q4: 当express中使用的变量在变化,我们要一直等到v满足某个条件时,怎么做

    使用for+switch组合。在switch组合外面包一层for来实现循环执行,当循环到某一次刚好满足某个条件case n时,执行case n中的逻辑,然后别忘了用break来退出for循环。

    func main() {
        v := 1
        go incre(&v)
        for {
            switch v {
            case 10:
                fmt.Println("222")
                break
            case 20:
                fmt.Println("333")
            }
            time.Sleep(1 * time.Second)
        }
    }
    
    func incre(v *int) {
        for i := 0; i < 20; i++ {
            time.Sleep(3 * time.Second)
            *v += 1
        }
    }
    

    运行结果:

    [work@ hello2]#go run 1.go
    222
    222
    222
    333
    333
    333
    

    运行10s后开始输出3个222(v增加到10),再过10s后,开始输出3个333(v增加到20)。说明switch里面额break并没有break for循环。为什么??有些资料说for switch里面的break是终止switch循环,但是switch本身是没有循环的,需要借助for来实现循环。那switch里面的break有什么作用???

    Q5: 接着上面Q4,我们发现switch里面的break好像一点作用都没有。那当在for+switch结构中,某次for循环后满足某个case条件,执行一次case里面的逻辑后我们想退出for循环怎么办?

    我们可以用break + name来指定break什么循环:

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
        v := 1
        go incre(&v)
    OPFOR: for {
            switch {
            case v < 3:
                fmt.Println("222")
                break OPFOR
            case v < 6:
                fmt.Println("333")
            }
            time.Sleep(1 * time.Second)
        }
    }
    
    func incre(v *int) {
        for i := 0; i < 20; i++ {
            time.Sleep(2 * time.Second)
            *v += 1
        }
    }
    

    可以看到我们使用了break OPFOR来终止for循环。

    Q6: 我们看到switch 后面可以带变量,表达式,也可以什么都不带,有什么区别?

    分两种情况,

    • 如果switch后面什么都不带,则每个case分支的表达式结果只要是boolena类型就可以
    • 如果switch后面带了某个变量,比如int类型的,则每个case分支的表达式结果必须跟这个变量的类型保持一致,这样switch case才能对条件做校验比较
      总结起来就是:落脚到每个case 语句都是boolean类型,true或者false
      示例1:
    func main() {
        v := 1
        switch {
        case v < 3:
            fmt.Println("222")
        case v < 6:
            fmt.Println("333")
        }
    }
    

    输出222
    示例2:

    func main() {
        v := 1
        switch v{
        case 1:
            fmt.Println("222")
        case 2:
            fmt.Println("333")
        }
    }
    

    输出222
    示例3:

    import (
        "fmt"
        "time"
    )
    
    func main() {
        v := 1
        switch v {
        case v < 3:
            fmt.Println("222")
        case v < 6:
            fmt.Println("333")
        }
    }
    

    运行结果:

    [work@ hello2]#go run 1.go
    # command-line-arguments
    ./1.go:5:2: imported and not used: "time"
    ./1.go:11:2: invalid case v < 3 in switch on v (mismatched types bool and int)
    ./1.go:13:2: invalid case v < 6 in switch on v (mismatched types bool and int)
    [work@ hello2]#
    

    总结

    • 1)default定义在其他case的前面或者后面没有任何影响。
    • 2)如果case1和case2都满足条件,谁排在前面执行谁
    • 3)没有default时,如果所有case都不满足条件,则switch case直接跳出,什么都不执行。即switch case结构本身没有循环执行能力。
    • 4)可以使用for+switch结构来让switch循环执行,但是switch里面的break没有任何意义。可以用break+循环名称来指定break哪种循环结构
    • 5)switch后面可以不带表达式,也可以带表达式(或者变量),对应的case 表达式也不一样,但是落脚到case最终的结构,只有true或者false两种情况。

    相关文章

      网友评论

          本文标题:golang switch case结构

          本文链接:https://www.haomeiwen.com/subject/sdpszctx.html