使用switch case语句在fizzbuzz上混淆输出

时间:2013-09-11 13:47:55

标签: go conditional fizzbuzz fall-through

这里有名的" fizz buzz" Go中的程序使用switch / case和if / else条件。问题是使用switch / case会产生意外的输出,而if / else(具有相同的条件)工作正常。我知道golang中的switch / case与其他C系列语言不同,但是这个代码片段有什么问题?

func main() {
const (
    FIZZ = 3
    BUZZ = 5
)

//section with switch/case gives unexpected output
for i := 1; i <= 30; i++ {
    switch {
    case i % FIZZ == 0:
        fmt.Printf("%d fizz\t", i%3)
        fallthrough
    case i % BUZZ == 0:
        fmt.Printf("%d buzz\t", i%5)
    }
    fmt.Printf("\t%d\n", i)
}

fmt.Printf("now towards the if/else\n")

//section with if/else works as expected
for i := 1; i <= 30; i++ {
    if i % FIZZ == 0 {
        fmt.Printf("%d fizz\t", i%3)
    }
    if i % BUZZ == 0 {
        fmt.Printf("%d buzz\t", i%5)
    }
    fmt.Printf("\t%d\n", i)
}

}

3 个答案:

答案 0 :(得分:6)

来自golang spec

  

秋季陈述

     

“fallthrough”语句将控制转移到第一个语句   表达式“switch”语句中的下一个case子句。它可能是   仅用作此类条款中的最终非空语句。

所以问题是:“情况i%FIZZ == 0”最后已经落后,所以“case i%BUZZ == 0”分支也被执行,但条件“i%BUZZ == 0”是没检查。

因此,要在golang中使用switch实现Fizz Buzz,您需要删除穿透并在顶部添加一个案例分支:play.golang.org。如您所见,“if-version”更简洁。

答案 1 :(得分:2)

您可以i%15使用fizzbuzz。此选项可提高性能。一个数字 - 一个分区和一个系统调用(sys_write)。并且不用担心fallthroughPlay

func main() {

    const (
        FIZZ = 3
        BUZZ = 5
        FIZZBUZZ = 15
   )

    for i := 1; i <= 30; i++ {
        switch {
        case i % FIZZBUZZ == 0:
            fmt.Printf("%d fizzbuzz\n", i)
        case i % FIZZ == 0:
            fmt.Printf("%d fizz\n", i)
        case i % BUZZ == 0:
            fmt.Printf("%d buzz\n", i)
        default:
             fmt.Printf("%d\n", i)
        }
   }
}

答案 2 :(得分:0)

//Example - between 1 and 100.

    for i := 1; i <= 100; i++ {
        output := ""
        if i%3 == 0 {
            output += "Fizz"
        }
        if i%5 == 0 {
            output += "Buzz"
        }
        if output == "" {
            fmt.Println(i)
        } else {
            fmt.Println(output)
        }
    }