使用switch case语句时,fizzbuzz输出混乱的问题。

huangapple go评论102阅读模式
英文:

Confusing output on fizzbuzz with switch case statement

问题

以下是使用Go语言中的switch/case和if/else条件语句编写的著名的“Fizz Buzz”程序。问题在于使用switch/case时生成了意外的输出,而if/else(具有相同条件)则正常工作。我知道在Go语言中,switch/case与其他C系语言不同,但是这段代码有什么问题呢?

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

    // 使用switch/case的部分生成了意外的输出
    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("现在使用if/else\n")

    // 使用if/else的部分按预期工作
    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)
    }
}

以上是要翻译的内容。

英文:

Here the famous "fizz buzz" program in Go using switch/case and if/else conditionals. The problem is that using switch/case is generating unexpected output while if/else (with same conditions) works fine. I know that switch/case in golang is different than other C-family languages, but what's wrong with this code fragment?

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

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

fmt.Printf(&quot;now towards the if/else\n&quot;)

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

}

答案1

得分: 6

根据golang的规范,"fallthrough"语句用于在"switch"语句的表达式中将控制转移到下一个case子句的第一条语句。它只能作为该子句中最后一个非空语句使用。

所以问题是:"case i % FIZZ == 0"在末尾使用了fallthrough,因此"case i % BUZZ == 0"分支也会被执行,但是条件"i % BUZZ == 0"没有被检查。

因此,要在golang中使用switch实现Fizz Buzz,你需要移除fallthrough,并在顶部添加一个额外的case分支。你可以在play.golang.org上看到,"if-version"更加简洁。

英文:

From the golang spec:

> Fallthrough statements
>
> A "fallthrough" statement transfers control to the first statement of
> the next case clause in a expression "switch" statement. It may be
> used only as the final non-empty statement in such a clause.

So the problem is: "case i % FIZZ == 0" has fallthrough at the end, so "case i % BUZZ == 0" branch is executed too, but the condition "i % BUZZ == 0" is not checked.

So to implement Fizz Buzz in golang using switch you need to remove fallthrough and add one more case branch to the top: play.golang.org. As you can see, "if-version" is more concise.

答案2

得分: 3

你可以使用i%15来实现fizzbuzz。这种方法可以提高性能。一个数字只需要进行一次除法和一次系统调用(sys_write)。而且不需要担心fallthrough的问题。点击这里进行演示。

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)
        }
   }
}
英文:

Your can use i%15 for fizzbuzz. This option gives a gain in performance. One number - one division and one system call (sys_write). And no worries about fallthrough. Play.

<!-- language: go -->

func main() {

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

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

答案3

得分: 0

//示例 - 在1和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)
		}
	}
英文:
//Example - between 1 and 100.

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

huangapple
  • 本文由 发表于 2013年9月11日 21:47:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/18743041.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定