golang switch case结构

舒小贱 · · 1606 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

结构:

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结构

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1606 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传