Goにもenumがあるような感じで書かれてる記事もあるようですが、 実際にはC言語のようなenumはサポートされてないんですね。 かわりに、iotaという特殊な変数を使うのだとか。
Go言語では、enumをサポートしていません。その代わりに、特殊な名前iotaを使って、ひとつのconst宣言内で、連続して増加する値を得ることができます。const内で、初期化式が省略されたときは、前の式が再利用されます。
関数の引数のチェックには有用なんですけどね、enum。 まぁ、C言語だと中身は整数値だと定義されちゃってるという不幸な仕様なためキャスト可能なので、 何も考えてない人が使うと不幸しか起こらないんですけどね。 しかも、コンパイラによって何バイトの整数使うか変わってくるんですよね……。 死ねます。
まぁそれはさておき、C言語のenumでも、デバッグのログ表示に四苦八苦するんですが、 goにはstringerなるものがあるらしい。 情報元は、例によってQiita(のコメント)。
constのString()を自動生成するstringerというツールが公式でサポートされてますよ
http://qiita.com/ksato9700/items/6228d4eb6d5b282f82f6#comment-371a5768589b45b45a2e
こちらのページ が大いに参考になりますし、 godocのページ もありまっせ。
使い方ですが、まずは go get
が必要みたいです。
階層が深いので若干面倒……。
$ go get golang.org/x/tools/cmd/stringer
次に、以下のようなコードを準備しました。
package main
import "fmt"
//go:generate stringer -type hoge
type hoge int
const (
Alice hoge = iota
Bob
Carol
Dave
Eve
Frank
Godzilla
)
func main() {
var test hoge
for test = Alice; test <= Godzilla; test++ {
fmt.Println(test)
}
}
なんか、整数型のtypeじゃないと駄目みたいなので hoge
とかいう型つくってます。
その時点で既に違和感ありますが……まぁ、そのあたりは感じないフリをして。
この、コメントにある go:generate stringer -type hoge
というのがミソで、
こちらを指定したあとに
$ go generate
とすると、以下のようなコード (hoge_string.go) を生成してくれました。
// Code generated by "stringer -type hoge"; DO NOT EDIT
package main
import "fmt"
const _hoge_name = "AliceBobCarolDaveEveFrankGodzilla"
var _hoge_index = [...]uint8{0, 5, 8, 13, 17, 20, 25, 33}
func (i hoge) String() string {
if i < 0 || i >= hoge(len(_hoge_index)-1) {
return fmt.Sprintf("hoge(%d)", i)
}
return _hoge_name[_hoge_index[i]:_hoge_index[i+1]]
}
ちなみに、 //
の後にスペースを入れたら認識してくれず、コード生成してくれませんでした。
まじかよぉ……ぅ.
そのあと、 go generate
と go build
を実行して stringer
を実行すると、
$ ./stringer
Alice
Bob
Carol
Dave
Eve
Frank
Godzilla
と期待した通りの挙動をしてくれました。
いやぁ、これは便利…………かなぁ? まぁ、もちろんログ吐くときは便利だけど、 こんなツールとして対応するより、ちゃんとenum作ってくれてコンパイル時にエラー吐いてくれて、 printlnに渡したら文字列表示してくれた方が幸せなのだが……。
まぁ、静的に解析するのは難しいか……。 テストも書くのも難しくなりそうだし…………うーん。