【问题标题】:Does a break statement break from a switch/select?break 语句是否从 switch/select 中断?
【发布时间】:2012-06-21 16:14:01
【问题描述】:

我知道switch/select 语句在每个案例之后都会自动中断。我想知道,在以下代码中:

for {
    switch sometest() {
    case 0:
        dosomething()
    case 1:
        break
    default:
        dosomethingelse()
    }
}

break 语句是退出 for 循环还是仅退出 switch 块?

【问题讨论】:

    标签: select switch-statement go break


    【解决方案1】:

    是的,break 打破了内部switch

    https://play.golang.org/p/SZdDuVjic4

    package main
    
    import "fmt"
    
    func main() {
    
    myloop:
        for x := 0; x < 7; x++ {
            fmt.Printf("%d", x)
            switch {
            case x == 1:
                fmt.Println("start")
            case x == 5:
                fmt.Println("stop")
                break myloop
            case x > 2:
                fmt.Println("crunching..")
                break
            default:
                fmt.Println("idling..")
            }
        }
    }
    
    0idling..
    1start
    2idling..
    3crunching..
    4crunching..
    5stop
    
    Program exited.
    

    【讨论】:

    • 这个答案没有说明没有标签的break 语句如何有用。 case x &gt; 2: 中的 break 语句实际上是一个空操作。
    【解决方案2】:

    这个问题可能已经太老了,但我仍然认为标签会使我们的代码变得更难阅读。 而不是打破 for inside select,只需为循环设置一个标志并在调用 break 之前在 select-case 内处理它。 例如:

    loop := true
    for loop {
        select {
        case <-msg:
            // do your task here
        case <-ctx.Done():
            loop = false
            break
        }
    }
    

    【讨论】:

    • 如果你不想泄露循环变量,你也可以在for循环for loop := true; loop; {}的范围内声明它。游乐场:play.golang.org/p/dNChUECkbfd
    【解决方案3】:

    只是从一个开关块。 Golang 自己的代码中有很多示例可供您检查(比较 inner breakouter break)。

    【讨论】:

      【解决方案4】:

      它只退出开关块。

      【讨论】:

        【解决方案5】:

        这应该可以解释。

        for{
            x := 1
            switch {
            case x >0:
                fmt.Println("sjus")
            case x == 1:
                fmt.Println("GFVjk")
            default:
                fmt.Println("daslkjh")
            }
        }
        }
        

        永远运行

        for{
            x := 1
            switch {
            case x >0:
                fmt.Println("sjus")
                break
            case x == 1:
                fmt.Println("GFVjk")
            default:
                fmt.Println("daslkjh")
            }
        }
        }
        

        再次,永远运行

        但是

        package main
        
        import "fmt"
        
        func main() {
        d:
        for{
        x := 1
            switch {
            case x >0:
                fmt.Println("sjus")
                break d
            case x == 1:
                fmt.Println("GFVjk")
            default:
                fmt.Println("daslkjh")
            }
        }
        }
        

        将打印 sjus ...清楚吗?

        http://play.golang.org/p/GOvnfI67ih

        【讨论】:

        • 嗯,我添加了一个 go play 链接,这可能会有所帮助。
        【解决方案6】:

        Break statements, The Go Programming Language Specification.

        “break”语句终止最里面的“for”的执行, “switch”或“select”语句。

        BreakStmt = "break" [ Label ] .
        

        如果有标签,它必须是一个封闭的“for”,“switch” 或“选择”语句,这是执行终止的语句 (§For 语句、§Switch 语句、§Select 语句)。

        L:
          for i < n {
              switch i {
              case 5:
                  break L
              }
          }
        

        因此,您示例中的 break 语句终止了 switch 语句,即“最内层”语句。

        【讨论】:

        • select {} 中的break 只能选择一个case 的用例是什么?
        • 因为即使选择了单个 case,它也可能有一个更长的实现,它使用 break 来终止 case 的执行,就像你可以从函数中的任何地方返回一样。
        【解决方案7】:

        一个有希望的说明性示例:

        loop:
        for {
                switch expr {
                case foo:
                        if condA {
                                doA()
                                break // like 'goto A'
                        }
        
                        if condB {
                                doB()
                                break loop // like 'goto B'                        
                        }
        
                        doC()
                case bar:
                        // ...
                }
        A:
                doX()
                // ...
        }
        
        B:
        doY()
        // ....
        

        【讨论】:

          猜你喜欢
          • 2013-08-20
          • 2011-03-12
          • 2010-09-30
          • 2013-12-18
          • 2018-09-17
          • 2018-01-21
          • 2016-12-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多