Go 言語には注釈がありません。 Go 言語がアノテーションをサポートしない理由: 1. Go は設計において明確で明示的なプログラミング スタイルを好みます; 2. 既存のコード メソッドと比較して、この新しいデコレータ メソッドは既存のメソッド以上の機能を提供しません。元の設計アイデアを覆すのに十分な量; 3. コミュニティ内の投票からの支持がほとんどありません。
このチュートリアルの動作環境: Windows 7 システム、GO バージョン 1.18、Dell G3 コンピューター。
特別なことは、Go には他の言語にはないいくつかの機能があることです。最も古典的なものは、N 人の Java 学生が Go 言語のアノテーションがどこにあるのかを探しており、常に説明しなければならないというものです。
この目的を達成するために、今日は Jianyu が Go 言語のアノテーションの使用法と状況について説明します。
アノテーションが初めて登場した場所は見つかりませんでした。ただし、アノテーションの使用において Java アノテーションが最も古典的であることは明らかであり、理解を容易にするために、Java に基づくアノテーションについて予備的な理解を行います。
2002 年、JSR-175 は、Java プログラミング言語用のメタデータ ツールを提供する「A Metadata Facility for the Java Programming Language」を提案しました。
これは、最も広く使用されているアノテーション (アノテーション) のソースです。例は次のとおりです。
// @annotation1// @annotation2func Hello() string { return ""}
は、アノテーション識別子として「@」でフォーマットされます。
@wikipedia のアノテーションの例から抜粋:
//等同于 @Edible(value = true) @Edible(true) Item item = new Carrot(); public @interface Edible { boolean value() default false; } @Author(first = "Oompah", last = "Loompah") Book book = new Book(); public @interface Author { String first(); String last(); } // 该标注可以在运行时通过反射访问。 @Retention(RetentionPolicy.RUNTIME) // 该标注只用于类内方法。 @Target({ElementType.METHOD}) public @interface Tweezable { }
上の例では、一連の定義はアノテーションを通じて行われます。宣言、割り当てなど。言語の既存の注釈に慣れていない場合、またはより複雑な注釈を作成する場合は、理解するのにある程度のコストがかかります。
業界ではよく、アノテーションは「ソースコード上のエンコード」であると言われています アノテーションの存在には明らかなメリットとデメリットがあります。どう思いますか?
アノテーションの機能は次の点に分かれます。
コンパイラに提供される情報: 注釈は、エラーを検出したり、警告をサポートしたりするためにコンパイラーで使用できます。
コンパイル時およびデプロイメント時の処理: ソフトウェア ツールは注釈情報を処理して、コードや XML ファイルなどを生成できます。
実行時処理: 一部の注釈は実行時にチェックでき、他の目的に使用できます。
Go 言語自体はネイティブではありません。強力なサポート アノテーションは次の 2 つのタイプに限定されます:
しかし、最初に押す これは関数のアノテーションとして使用するのに十分ではなく、Python のようなデコレータの動作を形成することもできません。
誰かが Go の問題に関して同様の提案をしました。
Go コントリビューターである @ianlancetaylor が明確な答えを出しました。Goは、明確で明示的なプログラミング スタイルを優先するように設計されています。
考えることの利点と欠点は次のとおりです:可読性がより重要であると考えています. もう少しコードを書いたとしても、比較検討した結果、まだ許容可能ですバランス。 。
虽然 Go 语言官方没有原生的完整支持,但开源社区中也有小伙伴已经放出了大招,借助各项周边工具和库来实现特定的函数注解功能。
GitHub 项目分别如下:
使用示例如下:
package tourdefrance//go:generate golangAnnotations -input-dir .// @RestService( path = "/api/tour" )type TourService struct{}type EtappeResult struct{ ... }// @RestOperation( method = "PUT", path = "/{year}/etappe/{etappeUid}" )func (ts *TourService) addEtappeResults(c context.Context, year int, etappeUid string, results EtappeResult) error { return nil}
对 Go 注解的使用感兴趣的小伙伴可以自行查阅使用手册。
我们更多的关心,Go 原生都没支持,那么开源库都是如何实现的呢?在此我们借助 MarcGrol/golangAnnotations 项目所提供的思路来讲解。
分为三个步骤:
解析代码。
模板处理。
生成代码。
首先,我们需要用用 go/ast 标准库获取代码所生成的 AST Tree 中需要的内容和结构。
示例代码如下:
parsedSources := ParsedSources{ PackageName: "tourdefrance", Structs: []model.Struct{ { DocLines: []string{"// @RestService( path = "/api/tour" )"}, Name: "TourService", Operations: []model.Operation{ { DocLines: []string{"// @RestOperation( method = "PUT", path = "/{year}/etappe/{etappeUid}"}, ... }, }, }, },}
我们可以看到,在 AST Tree 中能够获取到在示例代码中所定义的注解内容,我们就可以依据此去做很多奇奇怪怪的事情了。
紧接着,在知道了注解的输入是什么后,我们只需要根据实际情况,编写对应的模板生成器 code-generator 就可以了。
我们会基于 text/template 标准库来实现,比较经典的像是 kubernetes/code-generator 是一个可以参考的实现。
代码实现完毕后,将其编译成 go plugin,便于我们在下一步调用就可以了。
最后,万事俱备只欠东风。差的就是告诉工具,哪些 Go 文件中包含注解,需要我们去生成的。
这时候我们可以使用 //go:generate
在 Go 文件声明。就像前面的项目中所说的:
//go:generate golangAnnotations -input-dir .
声明该 Go 文件需要生成,并调用前面编写好的 golangAnnotations 二进制文件,就可以实现基本的 Go 注解生成了。
今天在这篇文章中,我们介绍了注解(Annotation)的历史背景。同时我们针对 Go 语言目前原生的注解支持情况进行了说明。
也面向为什么 Go 没有像 Java 那样支持强大的注解进行了基于 Go 官方团队的原因解释。如果希望在 Go 实现注解的,也提供了相应的开源技术方案。
以上がGo言語にはアノテーションがありますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。