Help us understand the problem. What is going on with this article?

実行例と stringer から学ぶ go generate 入門

More than 3 years have passed since last update.

go generate とは

  • go generate は Go の標準ツール
    • コマンドラインから go generate と実行..
    • するとコードから //go:generate から始まるコメント行を検索し //go:generate command argument... というコメント行の全文から command のコマンドを argument... の引数付きで実行する
    • 任意のコマンドを実行できるが Go のコードを生成することを想定して作られている
  • 自動では実行されないので、任意のタイミングで手動で実行したり、メイクファイルに記載しておきビルド前に実行したり、ファイル変更を検知して実行したりする

go generate は何をしてくれるか

  • go generate と実行するとカレントディレクトリから *.go ファイルを検索して各ファイル毎に //go:generate から始まるコメント行を探して実行する
// ファイルとディレクトリの作成
$ mkdir g1 g2
$ echo -e 'package g1\n//go:generate echo one' > g1/file1.go
$ echo -e 'package g1\n//go:generate echo two' > g1/file2.go
$ echo -e 'package g2\n//go:generate echo three' > g2/file3.go

// g1 で実行. file1.go file2.go の go:generate コマンドが実行される
$ cd g1
$ go generate

one
two

// g2 で実行. file3.go の go:generate コマンドが実行される
$ cd ../g2
$ go generate

three

$ cd ../

// 親ディレクトリで再帰的に実行. すべてのファイルの go:generate コマンドが実行される
$ go generate ./...

one
two
three

// go:generate コマンド行には実行環境の情報を変数で渡せる
$ mkdir g3
$ echo -e 'package g3\n//go:generate echo $GOARCH -- $GOOS -- $GOFILE -- $GOLINE -- $GOPACKAGE' > g3/file4.go
$ cd g3
$ go generate

amd64 -- darwin -- file4.go -- 2 -- g3
  • このように go generate はコマンドを検索して(必要であれば環境を変数で渡して)コマンドを実行してくれるが、コード自体の解析などは行ってくれない。

stringer とは

  • stringer とは定数を定数名の文字列に変換する関数を生成するコマンド
  • stringer -type=Pill [file|dir] とすると file か dir のファイル一覧から Pill 型の定数を検索して、定数名の文字列を返す func (Pill) String() string を生成する
  • file も dir も指定しない場合はカレントディレクトリを dir として実行する
  • go generate からは Pill 型の定数の宣言されたコードかそのコードと同じディレクトリのコードに //go:generate stringer -type=Pill と記載して実行する

おわりに

  • なんとなく自分でも go generate に対応したツールが作れそうな気がしてきた
  • コードを検索して解析して生成する流れはある程度パターンがありそうだからジェネレータのジェネレータも作れるかもしれない
nirasan
フリーで開発者をしています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away