ホームページ  >  記事  >  バックエンド開発  >  gogenerateコマンドの機能は何ですか?

gogenerateコマンドの機能は何ですか?

青灯夜游
青灯夜游オリジナル
2023-01-30 15:07:171161ブラウズ

「gogenerate」コマンドは、コンパイル前に特定のタイプのコードを自動的に生成するために使用されます。多くの場合、コードの自動生成に使用され、コードがコンパイルされる前にソース コードに基づいてコードを生成できます。 「go generated」コマンドを実行すると、現在のパッケージに関連するソース コード ファイルがスキャンされ、「//go:generate」を含むすべての特別なコメントが検索され、特別なコメントに続くコマンドが抽出されて実行されます。

gogenerateコマンドの機能は何ですか?

このチュートリアルの動作環境: Windows 7 システム、GO バージョン 1.18、Dell G3 コンピューター。

Go 言語には一連の強力なツールが用意されています。これらのツールを柔軟に使用すると、プロジェクトの開発が容易になります。ツールセットには次のものが含まれます。

bug         start a bug report
build       compile packages and dependencies
clean       remove object files and cached files
doc         show documentation for package or symbol
env         print Go environment information
fix         update packages to use new APIs
fmt         gofmt (reformat) package sources
generate    generate Go files by processing source
get         add dependencies to current module and install them
install     compile and install packages and dependencies
list        list packages or modules
mod         module maintenance
run         compile and run Go program
test        test packages
tool        run specified go tool
version     print Go version
vet         report likely mistakes in packages

ツールのソース コードは $GOPATH/src/cmd/internal にあります。この記事では主に Go ツールの生成について説明します。

go 言語自動化ツール


go generated コマンドは、Go 言語バージョン 1.4 で新しく追加されたコマンドで、よく使用されます。自動コード生成の場合、コードがコンパイルされる前にソース コードからコードを生成します。 gogenerate を実行すると、現在のパッケージに関連するソース コード ファイルがスキャンされ、「//go:generate」を含むすべてのコメント ステートメントが検索され、コメントの後のコマンドが抽出されて実行されます。コマンドは実行可能プログラムになります。このプロセスは、シェル スクリプトの呼び出しと実行に似ています。

#利用方法

    特別なコメントを追加する
//go:generate command argument...
    生成コマンドを実行します
$ go generate [-run regexp] [-n] [-v] [-x] [build flags] [file.go... | packages]

    この特別なコメントは次のとおりです。必須 .go ソース コード ファイルに含まれています。
  • 各ソース コード ファイルには、複数の生成された特別なコメントを含めることができます。
  • go generated は、go build、go get、go test などのコマンドによってトリガーされないため、開発者が明示的に使用する必要があります。
  • コマンドの実行はシリアルであり、エラーが発生すると以降のコマンドは実行されません。
  • 特別なコメントは「//go:generate」で始まる必要があり、二重スラッシュの後にスペースは入れません。
  • 実行コマンドは、システム PATH (echo $PATH) にある実行可能プログラムである必要があります。

使用例

package mainimport "fmt"//go:generate echo GoGoGo!//go:generate go run main.go//go:generate echo $GOARCH $GOOS $GOFILE $GOLINE $GOPACKAGEfunc main() {
 fmt.Println("go rum main.go!")}
go generated コマンドを実行

$ go generate
GoGoGo!go rum main.go!amd64 darwin main.go 7 main

列挙型定数の String メソッドの実装


上記の Generate の簡単な紹介を読んでも、読者はこのツールの威力を実感できないかもしれません。Xiaocai Knife は、古典的なアプリケーションを提供します。このツールのシナリオ: 列挙定数の String メソッドの実装。


もう 1 つの公式ツールである stringer についてここで説明する必要があります。これは、一連の整数定数の String() メソッドを自動的に作成できます。 stringer は Go の公式リリースのツール セットには含まれていないため、自分でインストールして次のコマンドを実行する必要があります。

go get golang.org/x/tools/cmd/stringer
これはストリンガーのドキュメントから引用した例です。コードは次のとおりで、さまざまな Pill タイプの整数定数のセットを定義します。

package painkillertype Pill intconst (
    Placebo Pill = iota
    Aspirin
    Ibuprofen
    Paracetamol
    Acetaminophen = Paracetamol)
デバッグまたはその他の理由から、これらの定数を出力する必要があります。つまり、Pill には署名付きメソッドが必要です。

func (p Pill) String() string
これを達成するのはとても簡単です。

func (p Pill) String() string {
    switch p {
    case Placebo:
        return "Placebo"
    case Aspirin:
        return "Aspirin"
    case Ibuprofen:
        return "Ibuprofen"
    case Paracetamol: // == Acetaminophen
        return "Paracetamol"
    }
    return fmt.Sprintf("Pill(%d)", p)}
想像してみてください。新しい薬剤名のバッチがピル リストに追加された場合、薬剤名が追加または変更されるたびに、対応するシグネチャ関数も変更する必要があります。これは面倒で、見落としたり、間違ったりする可能性が高いのではないでしょうか?現時点では、ストリンガーを生成することでこの問題を解決できます。非常に簡単で、Pill を定義するコードにコメント ステートメントを追加するだけです。

//go:generate stringer -type=Pill
上記のコマンドは、ストリンガー ツールを実行して Pill タイプの String メソッドを生成することを表しています。デフォルトでは、pill_string.go ファイルに出力されます。実行は次のとおりです。

$ go generate
$ cat pill_string.go
// Code generated by stringer -type Pill pill.go; DO NOT EDIT.

package painkillerimport "fmt"const _Pill_name = "PlaceboAspirinIbuprofenParacetamol"var _Pill_index = [...]uint8{0, 7, 14, 23, 34}func (i Pill) String() string {
    if i = Pill(len(_Pill_index)) {
        return fmt.Sprintf("Pill(%d)", i)
    }
    return _Pill_name[_Pill_index[i]:_Pill_index[i+1]]}
このようにして、ピルの種類を変更するたびに、次のステートメントを実行するだけで済みます。

$ go generate
もちろん、これが面倒だと感じたり、generate ステートメントを実行するのを忘れることが心配な場合は、次に、 gogenerate ステートメントを Makefile に記述し、 go build コマンドの前に配置して、コードの生成とコンパイルを自動化できます。

Go ソース コード ドキュメントでは、列挙定数の String メソッドを実装するために go 生成ストリンガー ソリューションが広く使用されていることに言及する価値があります。 Xiaocai Knife のネイティブ Go 1.14.1 のソース コードには、次のように合計 23 の用途があります。

gogenerateコマンドの機能は何ですか?

#概要

この記事では、generate とは何か、何ができるのか、内部実装ロジックを深く理解するには、sort パッケージの下の zfuncversion.go から genzfunc.go の生成など、Go ソース コードでコードを生成する詳細なプロセスを確認できます。 Go ソースコードの宝庫には同様の実装ロジックが多数ありますので、以下を参照してください。


これらは、抽象構文ツリーを定義するための go/ast、抽象構文ツリーを解析するための go/parser、コードの書式設定を解析するための go/format、Go 字句タグ用の go/ など、Go コンパイラによって提供されるライブラリを使用します。等ソース ファイルを解析し、既存のテンプレートに従って新しいコードを生成します。このプロセスは、Web サービスでテンプレートを使用して HTML ファイルを生成するのと似ています。

【関連する推奨事項: Go ビデオ チュートリアル プログラミング教育

以上がgogenerateコマンドの機能は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。