Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

go generate 完全入門

593 views

Published on

プログラミング言語Go完全入門 質問会
https://mercari.connpass.com/event/174255/

Published in: Technology
  • Be the first to comment

go generate 完全入門

  1. 1. go generate 完全入門 2020-06-03 プログラミング言語Go完全入門 質問会 Takeshi Yaegashi
  2. 2. 自己紹介 八重樫 剛史 Takeshi Yaegashi ● 株式会社バンダイナムコスタジオ所属 ● Linux・Unix・OSS・低レベルなことが好きなエンジニア ● ブログ https://l0w.dev Qiita https://qiita.com/yaegashi ● 最近の仕事 ○ Raspberry Pi IoT 案件 (Go) スマホゲームアプリのサーバ開発 (Go) ○ 社内向け研究・開発インフラ構築 ● 過去の登壇 ○ Go Conference 2019 Autumn「Microsoft Graph API Library for Go」
  3. 3. 今日の話題 go generate 完全入門 Go コード生成概論(?) ● そもそも 5 分間の LT で完全入門できる ような話題ではない ● プログラミング言語 Go 完全入門 に go generate がなかったので、出来 心であやかったタイトルをつけてしまっ た… 新章のアナウンス!期待しています!
  4. 4. Go のコード生成とコードジェネレータ ● コード生成 ○ Go のプログラムをプログラムで自動生成すること ● コードジェネレータ ○ Go のプログラムを生成するプログラム ● コードジェネレータを作る ○ いわゆるメタプログラミング = プログラムを作るプログラムを作る ○ Go には様々なコード生成を支援する機能がある ● コードジェネレータを使う ○ Go のエコシステムでは様々なコードジェネレータが公開されている
  5. 5. どういうときにコード生成するのか ● テーブルやアセットの埋め込み ○ go-bindata, go-assets, statik … ファイルの内容を文字列リテラルに変換するツール ● 仕様書を元にしたコードの自動生成 ○ time, wtz.go … Windows タイムゾーン対応表の XML から map リテラルを生成している ○ msgraph.go … OData 仕様書の XML から API のコードを生成している ○ go-swagger … Open API 仕様書の YAML から API のコードを生成するツール ● コードを元にしたコードの自動生成 ○ stringer … コードを静的解析して const 定義から文字列を生成するツール ○ wire … コードを静的解析して DI のコードを生成するツール ● ジェネリクスやマクロの代替手段 ○ genny … コード生成のテンプレートの記述が楽になるツール
  6. 6. なぜコード生成するのか ● コーディングに必要な筋力の削減、つまらないミスの防止 ○ 似たようなコードを繰り返し人間が書くのは最小限にしたい ● 動的なデータや型、リフレクションを避ける ○ 静的なコードを徹底することで得られるメリット ■ 実行時のパフォーマンスの最適化 ■ 開発時のコーディング支援の最大化
  7. 7. コード生成を支援する Go の機能 ● //go:generate ディレクティブ ○ ソースコード中にコードジェネレータを実行するコマンドラインが書ける ○ $GOPACKAGE や $GOFILE といった環境変数がコードジェネレータに渡される ● コードフォーマッタ (gofmt, goimports, etc.) ○ コード整形の標準ツール、ライブラリとしても呼び出し可能 ○ コードジェネレータはインデントやインポートなどを気しなくてもよくなるので開発が楽 ● テンプレート (text/template) ○ 充実した機能を持つテンプレートエンジンが標準ライブラリで利用可能 ● ビルドタグ ○ // +build ignore でコードジェネレータのソースコードをビルドから除外する
  8. 8. コード生成したくなる Go の機能 ● ソースコードの静的解析 ○ 解析が容易な Go の文法、標準ライブラリ (ast) によるサポート ○ コードジェネレータは自分を呼び出したソースコードの解析が容易にできる ○ 汎用ツール向け ● 実行時のリフレクション ○ コードジェネレータに対象のコードを取り込み reflect で調べる ○ 特定プロジェクト専用のコード生成で静的解析が面倒くさいときに使う代替手段 ○ struct のフィールドやタグの情報は取れるが、コメントに書いた情報などは取れない
  9. 9. 実例:time (Windows タイムゾーン変換 map 生成) var abbrs = map[string]abbr{ "Egypt Standard Time": {"EET", "EET"}, // Africa/Cairo "Morocco Standard Time": {"+00", "+01"}, // Africa/Casablanca "South Africa Standard Time": {"SAST", "SAST"}, // Africa/Johannesburg "Sudan Standard Time": {"CAT", "CAT"}, // Africa/Khartoum ... <supplementalData> <version number="$Revision$"/> <windowsZones> <mapTimezones otherVersion="7e11200" typeVersion="2019b"> ... <!-- (UTC+02:00) Cairo --> <mapZone other="Egypt Standard Time" territory="001" type="Africa/Cairo"/> <mapZone other="Egypt Standard Time" territory="EG" type="Africa/Cairo"/> ... Windowsタイムゾーン仕様 windowsZones.xml 生成された map リテラル zoneinfo_abbrs_windows.go //go:generate env ZONEINFO=$GOROOT/lib/time/zoneinfo.zip go run genzabbrs.go -output zoneinfo_abbrs_windows.go //go:generate を含む zoneinfo.go
  10. 10. 実例:stringer (const の型に String() メソッド生成) const _Pill_name = "PlaceboAspirinIbuprofenParacetamol" var _Pill_index = [...]uint8{0, 7, 14, 23, 34} func (i Pill) String() string { if i < 0 || i >= Pill(len(_Pill_index)-1) { return "Pill(" + strconv.FormatInt(int64(i), 10) + ")" } return _Pill_name[_Pill_index[i]:_Pill_index[i+1]] } type Pill int const ( Placebo Pill = iota Aspirin Ibuprofen Paracetamol Acetaminophen = Paracetamol ) //go:generate go run golang.org/x/tools/cmd/stringer -type=Pill Pill の String() メソッドが 生成された pill_string.go Pill 型の const 定義と //go:generate を含む pill.go go run で呼び出す stringer コマンド
  11. 11. Go のコード生成を深く知るための資料 ● 自由度が高いゆえにわかりにくい・まちがいやすい ● go generate のマニュアルを読む ○ https://golang.org/cmd/go/#hdr-Generate_Go_files_by_processing_source ○ go help generate で読める ● go generate 登場時の記事を読む (Go 1.4 の頃; 2014 年末) ○ The Go Blog: Generating code https://blog.golang.org/generate ■ stringer を例として詳しく説明している ○ Go ganerate: A proposal https://golang.org/s/go1.4-generate
  12. 12. go generate のベストプラクティス ● Go Modules など、最近の Go に導入さ れた機能を踏まえたコード生成のベスト プラクティスをまとめました ● このスライドで紹介した実例についての 追加のトピックもあります ● 今後も内容は随時更新 本日も更新しました! https://qiita.com/yaegashi/items/d1fd9f7d0c75b2bb7446
  13. 13. おわり Happy Go code generating!

×