Go言語には、C言語やJavaにおける「enum(列挙型)」のような機能がありません。
Go言語をやり始めて最初にこれを知った時、 え嘘でしょ? と言いたくなりました。
が、実際には 定数定義とiota
を利用することでC言語における列挙型に近い振る舞いを実現することが可能です。
例えば、Red, Blue, Yellowを持つColorというenumを作る場合は以下のように定義します。
type Color int const ( Red Color = iota Blue Yellow )
で、iota
って何ですかって話なんですが。
識別子iota
は、定数宣言文(const
)内で使用される、型なしの連続する整数定数を表します。
本定数は予約語const
が現れた時に0に初期化されて、各定数定義の後に1ずつインクリメントされます。
ちなみに読み方は「イオタ」。
例えば、iota
を使って定数(val0, val1, val2)を定義すると、各定数の値は0, 1, 2になります。
const ( val0 = iota // val0 == 0 val1 = iota // val1 == 1 val2 = iota // val2 == 2 )
iota
は 0 から開始され、(以下例のように)iotaを省略しても評価されて連続する整数がセットされます
const ( val0 = iota // val0 == 0 val1 // val1 == 1 val2 // val2 == 2 )
ということで、冒頭のColor
は、実際には以下コード内のコメントのように、Redに0, Blueに1, Yellowに2がセットされています。
これにより疑似的にenumを表現しています。
type Color int const ( Red Color = iota // Red == 0 Blue // Blue == 1 Yellow // Yellow == 2 )
実際にはenumとして作成したtypeに対してfmt.Stringer
インターフェースを実装(String
メソッドを用意)しておくのが良いです。
(Stringer
インターフェースを実装しておいた方がfmt.Println
等で表示した際に分かりやすくなります)
そこまでやるとColor
の定義は以下のようになります。
type Color int const ( Red Color = iota Blue Yellow ) func (c Color) String() string { switch c { case Red: return "Red" case Blue: return "Blue" case Yellow: return "Yellow" default: return "Unknown" } }
(String
メソッドのこの実装はどうにかならないんだろうかと良く思いますが・・・)
というわけでGo言語でもenumを定義することができました。