🦍
go generate 入門
Go で構造体を書く際に Getter を手で書くのは面倒だなと感じました。
普段は Rust で開発していて、derive-getters クレートが便利なので、Go でも同じようなことができないかなと調べたところ go generate
で実現できることがわかったので試してみました。
go generate とは
概要
- Go 1.14 で導入された機能で、コードを自動生成するための仕組み
- コード内に
//go:generate
ディレクティブを記述することで、指定されたコマンドを実行し、その出力をコードとして取り込むことが可能
利点
- コードの冗長性を削減し、可読性を向上させることができる
- コード生成を自動化することで、開発者の負担を軽減できる
- テンプレートエンジンやコードジェネレータなどのツールと連携することで、より複雑なコード生成を行うことができる
使い方
- コード内に
//go:generate
ディレクティブを記述(//
とgo:generate
の間にはスペースがないことに注意) - ディレクティブに実行したいコマンドとオプションを記述
-
go genrate
コマンドを実行する
go generate [-run regexp] [-n] [-v] [-x] [build flags] [file.go... | packages]
例
//go:generate stringer -type MyStruct
package main
import "fmt"
type MyStruct struct {
ID int
Name string
Age int
}
func main() {
s := MyStruct{ID: 1, Name: "Taro", Age: 30}
fmt.Println(s.String()) // 自動生成された String() メソッドが呼び出されます
}
上記の例の場合は、go genrate
を実行すると、stringer
が実行されr MyStruct
型に String()
メソッドが自動生成される。
詳細
- 生成されたコードには、自動生成されたファイルであることを明記する必要がある
^// Code generated .* DO NOT EDIT\.$
Getters を自動生成してみる
やることは単純で、下記の4ステップです。
- フォルダ内の
*.go
ファイルを見つける -
//go:generate getters
と記載されている構造体を見つける -
getters
が付与された構造体のフィールドから Getter レシーバーを作成する -
filename_getters.go
として出力
go-getters を使ってみる
実際に作ったのがこちら
https://github.com/yusei-wy/go-getters
使い方は
-
go install github.com/yusei-wy/go-getters@latest
でインストール - getters ディレクティブを Getters を生成したい構造体に記述
-
go-getters
コマンド実行
まとめ
以上 go generate を試してみたメモでした。
作っていて思ったのは、これちゃんと go ディレクティブになっているのかなと、正しい使い方ができてるかが心配なのでおかしなところがあれば教えて下さい。
Discussion