1
0

More than 3 years have passed since last update.

Go言語でFizzBuzzを書いてみた

Posted at

はじめに

正月休み時間があったので Go 言語を勉強しました。
基本文法の確認のため FizzBuzz を書いてみたら Go 言語ならではの面白い書き方ができるなー、と思ったので投稿することにしました。

FizzBuzz のルール

  • 1 から 100 まで数字を出力する
  • その数字が 3 で割り切れるなら Fizz と出力する
  • その数字が 5 で割り切れるなら Buzz と出力する
  • その数字が 3 でも 5 でも割り切れるなら FizzBuzz と出力する

コード


type FizzBuzzInt int

func (i FizzBuzzInt) String() string {
    switch {
    case i%15 == 0:
        return "FizzBuzz"
    case i%3 == 0:
        return "Fizz"
    case i%5 == 0:
        return "Buzz"
    default:
        return strconv.Itoa(int(i))
    }
}

func main() {
    i := FizzBuzzInt(1)
    for i <= 100 {
        fmt.Printf("%3d => %v\n", i, i)
        i++
    }
}

実行結果

  1 => 1
  2 => 2
  3 => Fizz
  4 => 4
  5 => Buzz
  6 => Fizz
  7 => 7
  8 => 8
  9 => Fizz
 10 => Buzz
 11 => 11
 12 => Fizz
 13 => 13
 14 => 14
 15 => FizzBuzz
 16 => 16
 17 => 17
 18 => Fizz
 19 => 19
 20 => Buzz
(以下略)


解説

型定義

type FizzBuzzInt int

上記のようにして int 型を元に新たな型を定義できる。
このように定義した型は基本的には int と同じように扱うことができる。

var i FizzBuzzInt = 10

// 算術演算子や比較演算子はそのまま使用可能
i++
fmt.Println(i) // => 11
fmt.Println(i % 2) // => 1
fmt.Println(i <= 10) // => false

ただし型チェックは FizzBuzzInt 型として行われるので、
引数が int 型の関数に渡すとコンパイルエラーになる。

int型の関数に渡した場合
func printInt(i int) {
    fmt.Println(i)
}

var i FizzBuzzInt = 10

// 引数の型が一致しないのでコンパイルエラーになる
printInt(i)

// FizzBuzzInt と int は相互変換可能なので、キャストしてやれば問題ない
printInt(int(i))

メソッド

Go言語では にメソッドを紐付ける。
例えば以下のように、整数型(を元に定義した型)に奇数判定用のメソッドを付けることができる。

整数型にメソッドを追加する
type MyInt int

// MyInt 型に IsOdd メソッドを紐付ける
func (mi MyInt) IsOdd() bool {
  return mi%2 != 0
}

i := MyInt(1)
i.IsOdd() // => true
i++
i.IsOdd() // => false

Stringer インターフェース

Java でいう Object#toString() みたいなもの。
string 型を返す String() というメソッドを定義しておくと、
Println に渡したときなどにそのメソッドが呼ばれる。

文字列関係の書式指定子 (%v %s %q %x %X)でのみ String() メソッドが呼ばれる仕様なので、書式指定子で出力内容を切り替えることが可能です。

Stringerインターフェースの例

type MyInt int

func (mi MyInt) String() string {
  return "hoge"
}

i := MyInt(3)
fmt.Printf("%d\n", i) // => 3
fmt.Printf("%v\n", i) // => hoge

参考: https://golang.org/pkg/fmt/#pkg-overview

コード

以上を踏まえてコメントを追記しました。


// FizzBuzzInt は int を元にした型
type FizzBuzzInt int

// FizzBuzzInt 型に Stringer インターフェースを実装。
// 出力するときにこのメソッドが呼ばれ、FizzBuzz のロジックで出力内容を切り替える
func (i FizzBuzzInt) String() string {
    switch {
    case i%15 == 0:
        return "FizzBuzz"
    case i%3 == 0:
        return "Fizz"
    case i%5 == 0:
        return "Buzz"
    default:
        return strconv.Itoa(int(i)) // Itoaの引数は int 型なのでキャストして渡す
    }
}

func main() {
    i := FizzBuzzInt(1) // i は FizzBuzzInt 型で初期化

    // 比較演算は int と同様に使える
    for i <= 100 {
        // %d は int として表示、%v は String() メソッドの結果を表示
        fmt.Printf("%3d => %v\n", i, i)

        // インクリメントも int と同様に使える
        i++
    }
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0