5

これは、switch/case および if/else 条件を使用した Go の有名な「fizz Buzz」プログラムです。問題は、スイッチ/ケースを使用すると予期しない出力が生成される一方で、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)
}

}

4

3 に答える 3

6

golang仕様から:

フォールスルー ステートメント

"fallthrough" ステートメントは、式 "switch" ステートメント内の次の case 句の最初のステートメントに制御を移します。これは、そのような句の最後の空でないステートメントとしてのみ使用できます。

問題は、「case i % FIZZ == 0」は最後にフォールスルーがあるため、「case i % BUZZ == 0」の分岐も実行されるが、条件「i % BUZZ == 0」はチェックされない。

したがって、switch を使用して golang で Fizz Buzz を実装するには、フォールスルーを削除し、もう 1 つのケース ブランチを上部に追加する必要があります: play.golang.org。ご覧のとおり、「if-version」の方が簡潔です。

于 2013-09-11T13:56:03.353 に答える
3

i%15に使用できますfizzbuzz。このオプションにより、パフォーマンスが向上します。1 つの数値 - 1 つの除算と 1 つのシステム コール (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)
        }
   }
}
于 2014-09-19T20:52:39.207 に答える