はじめに
はじめまして。今年の1月にHAROiDに入社した鈴木(@yudppp)です。
いつもMacBookProにHHKBを乗せて仕事をしています。
HAROiDでは多くのシステムでGolangを採用しています。 個人的にもGolangはSimpleで書きやすく好きな言語なのですが、簡素な言語仕様のため手で書くコードが他の言語に比べて増えてしまいがちです。
そこでコードを自動生成できるgo generate
を紹介していきます。
go generateとは
Golangの1.4から追加されたコマンドでコードの自動生成を行うことができます。
こちらの公式ブログでも紹介されています。
実際にstringerを使って、go generate
の使い所を見てみたいと思います。
stringerとは
定数群にstringerをかけることによって、interfaceのStringerの関数のfunc (t T) String() string
の実装が行われます。
また、Stringerは出力時の返す値を定義するものです。
使い方は簡単で下記のようにgo get
してコマンドを入手します。
$ go get golang.org/x/tools/cmd/stringer
このようにいくつかの薬が定数で定義しているとします。
package painkiller type Pill int const ( Placebo Pill = iota Aspirin Ibuprofen Paracetamol Acetaminophen = Paracetamol )
fmt.Println(Placebo)
をすると、数値の0
が出力されます。0
だと何者なのかが分かり難いため、分かりやすい文字列にしたいです。
そこでstringer
コマンドを実行すると
$ stringer -type=Pill
Stringerが実装され、再度fmt.Println(Placebo)
を試してみると、今度はPlacebo
という文字列が表示されました。
すごく簡単に出力を文字列に変更することができました。
しかし薬の種類が増えたときに再度コマンドを実行しなければなりません。 ひとつのときはMakefileにでも1行書いておけばよいのですが、他のものにもstringerを実行させたくなったときにその分Makefileに追加して書いていかなければいけなくなってしまいます。
そこでgo generateを使っていきます。
先ほどのfileに
package painkiller //go:generate stringer -type=Pill type Pill int const ( Placebo Pill = iota Aspirin Ibuprofen Paracetamol Acetaminophen = Paracetamol )
と1行コメントを追加します。
そのあとに
$ go generate
を行うと、コメントを解析して先ほどのstringer
コマンドをした時と同じ結果が得られるようになります。
//go:generate {コマンド}
とするだけで自動で生成されるので簡単に処理を自動化することができます。
jsonのタグを自動生成する
普段Golangを書いていて特に面倒くさいと思うことのひとつにJSONを返すAPIを作っていた時のレスポンスに使われるstructのタグを書きたくないと毎日思っています。
type User struct { UserID string `json:"user_id"` Name string `json:"name"` }
スネークケース返すようなAPIを普段実装しているのですが、スネークケースで返すようにしたいだけなのに1つ1つに設定が必要で、やたら手間がかかります。
理想はdefaultはスネークケースで返すようにして、何か指定したい時だけ(たとえばomitempty
やstring
など)タグを書くようにしていきたいです。
ということで作ってみました。
AST(抽象構文木)を初めて触ったのですがgolangでは簡単に扱うことができ、三時間ほどで動くものができました。
// go:generate json_snake_case -type=User type User struct { UserID string Name string }
上記のように宣言しgo generate
するとMarshalerをスネークケースで返すように勝手に実装してくれます。
使い方等細かい内容はREADME.mdに記載しています。
同じようにタグを書くのが面倒くさいと思ってる方は是非使ってみてください。 不具合等ありましたらissueやPR等いただけたらと思います。
最後に
今後も面倒くさい仕事を自動化して、自分の仕事を減らしていきたいです。