分享
  1. 首页
  2. 文章

golang switch case结构

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

结构:

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

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

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏