🐥

goのenumは文字列でいいのではないかという話

2022/03/13に公開

goにおけるenumの一般的な定義

世の中で真っ当とされているgoにおけるenumの定義は、

type Zodiac int

const (
	Rat    Zodiac = iota // 子
	Ox                   // 丑
	Tiger                // 寅
	:
)

ですね

とはいえ数値でJSON化されたり、ログ出されたり、DBに書き込まれたりされても、
理解が一歩遅れるので、文字列化は欲しくなるわけです。
enumを文字列化するために、String() 設けたりします。

func (z Zodiac) String() string {
	switch z {
	case Rat:
		return "Rat"
	case Ox:
		return "Ox"
	case Tiger:
		return "Tiger"
	:
	}
	return ""
}

何を書かされているんだ…

という悩みを解決するために Stringer とか Apache Thrift とかがよく使われます

ハナから文字列で良くない?

そもそも、別に数値である必要はないのでは。

type Zodiac string

const (
	Rat    = Zodiac("Rat")
	Ox     = Zodiac("Ox")
	Tiger  = Zodiac("Tiger")
	Rabbit = Zodiac("Rabbit")
	Dragon = Zodiac("Dragon")
	Snake  = Zodiac("Snake")
	Horse  = Zodiac("Horse")
	Sheep  = Zodiac("Sheep")
	Monkey = Zodiac("Monkey")
	Cock   = Zodiac("Cock")
	Dog    = Zodiac("Dog")
	Boar   = Zodiac("Boar")
)

seealso: https://play.golang.org/p/kqHy0zm0vwn

String()MarshalText()MarshalYAML() もいらない。

ライトに定義するならこれで大体良いのでは。
仕事でも3年ほど同じものを開発し続けていますが、そこでenumを定義するときもおおよそこれで困ってません。
必要なら諸々書けばいいし、必要ないなら書かなければいい。

最初に書くのがダルいって声は聞こえそうですけど、このレベルならSnippetでどうにでもなります。
Goは割と手軽にGenerateしたら良いよという文化ですが、あんまりGenerate偏重ってのもどうなのかなと思っての提案でした。

スペシャルサンクス

@po3rin さんの Vim plugin のおかげで、この記事はとても快適に書けました。
https://qiita.com/po3rin/items/9b17a206fd8661235aa1

Discussion