はじめに
GolangでJavaのEnumっぽい機能が欲しいなと思って調べた結果を残しておきます。
今回やりたかったことは
- Enum自体はGolangの文法に沿ってcamel caseになっている
- Enum変換元はstringでsnake caseになっている
Webサービスのquery parameterはsnake caseだけど、golangのロジックに入ってくるタイミングではcamel caseになっていてほしい、という感じです。
調べたこと
ググってみると、やはり同じことを思う人は結構いるみたいでした。
その中でも以下については詳しく見てみました。
- Go言語 - enumを定義する
- GoLangでJavaのenumっぽいライブラリ作った話
- Re: GoLangでJavaのenumっぽいライブラリ作った話
- 4 iota enum examples
1は要件を満たせそうでした。が、enumを作るたびにswitch caseで変換していくのは流石に面倒だな…ということで別の方法を探しました。
2はiotaがあるのにstructを作るのもなーと思ってやめました。
3は公式サポートの自動生成でいいと思ったのですが、得られるstringがcamel caseのままだったので、今回の要件には合いませんでした。
そして最後に出会ったのが4でした。今回の要件的にはこれが一番いいな、ということでこれを採用することにしました。
以下4の記事から引用
1
2
3
4
5
6
7
8
|
type Suite int
const (
Spades Suite = iota
Hearts
Diamonds
Clubs
)
|
1
2
3
|
func (s Suite) String() string {
return [...]string{"Spades", "Hearts", "Diamonds", "Clubs"}[s]
}
|
今回採用したEnum
Enum => stringには簡単に変換することが出来ました。
しかし、string => Enumの変換をうまくすることが出来ませんでした…
試行錯誤した末、最終的には以下の形に落ち着きました。
https://play.golang.org/p/Bvc6neemVw9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
package main
import "fmt"
type Weekday int
const (
Unknown Weekday = iota
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
func NewWeekday(strWeekday string) Weekday {
for i, name := range Sunday.Names() {
if strWeekday == name {
return Weekday(i)
}
}
return Unknown
}
func (e Weekday) Names() []string {
return []string{
"unknown",
"sunday",
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
}
}
func (e Weekday) String() string {
return e.Names()[e]
}
func switchWeekday(weekday Weekday) {
switch(weekday) {
case Monday:
fmt.Println("Hello monday!!")
case Friday:
fmt.Println("Hello friday!!")
case Unknown:
fmt.Println("Unknown weekday....")
default:
fmt.Println("not found weekday...")
}
}
func main() {
fmt.Printf("monday = %+v\n", Monday)
input := "friday"
weekday := NewWeekday(input)
switchWeekday(weekday)
input = "nothing"
weekday = NewWeekday(input)
switchWeekday(weekday)
}
|
ポイント
- EnumのタイプにUnknownを定義して見つからない場合はUnknownを返すようにした
- NewWeekday でstringをinputにWeekday型のenumを返す
- String()でEnumの文字を取得できる
まとめ
これで今回の要件を満たせるEnumを定義することが出来ました!
ただ、やはりGolangでEnumを定義するのは面倒ですね…
引き続きナニカ書いていきます♪