假如给Go语言加上注解,程序会变怎样?
作为一位 Go 程序员,你会发现身边的同事大多都拥有其他语言的编写经验。那势必就会遇到一点,要把新学到的知识和以前的知识建立连接。
特殊在于,Go 有些特性是其他语言有,他没有的。最经典的就是 N 位 Java 同学寻找 Go 语言的注解在哪里,总要解释。
为此,今天煎鱼就带大家了解一下 Go 语言的注解的使用和情况。
什么是注解
了解历史
注解(Annotation)最早出现自何处,翻了一圈并没有找到。但可以明确,在注解的使用中,Java 注解最为经典,为了便于理解,因此我们基于 Java 做初步的注解理解。
在 2002 年,JSR-175 提出了 《A Metadata Facility for the Java Programming Language》,也就是为 Java 编程语言提供元数据工具。
这就是现在使用最广泛地注解(Annotation)的来源。示例如下:
// @annotation1
// @annotation2
func 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 注解在哪里
现状
Go 语言本身并没有原生支持强大的注解,仅限于以下两种:
编译时生成:go:generate
编译时约束:go:build
但这先按不足以作为一个函数注解来使用,也无法形成像 Python 那样的装饰器行为。
为什么不支持
Go issues 上有人提过类似的提案:
Go Contributor @ianlancetaylor 给出了明确的答复,Go 在设计上更倾向于明确的、显式的编程风格。
思考的优缺点如下:
优势:不知道 Go 能从添加装饰器中得到什么好处,没能在 issues 上明确论证。
缺点:是明确的,会存在意外设置的情况。
因如下原因,没有接受注解:
对比现有代码方法,这种装饰器的新的方法没有提供比现有方法更多的优势,大到足矣推翻原有的设计思路。
社区内的投票,支持的也很少(基于表情符号的投票),用户反馈不多。
可能有小伙伴会说了,有注解做装饰器了,代码会简洁不少。
对此 Go 团队的态度很明确:
Go 认为可读性更重要,如果只是额外多写一点代码,在权衡后,还是可以接受的。
用 Go 实现注解
虽然 Go 语言官方没有原生的完整支持,但开源社区中也有小伙伴已经放出了大招,借助各项周边工具和库来实现特定的函数注解功能。
GitHub 项目分别如下:
MarcGrol/golangAnnotations
u2takey/go-annotation
使用示例如下:
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 项目所提供的思路来讲解。
分为三个步骤:
解析代码。
模板处理。
生成代码。
解析 AST
首先,我们需要用用 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 语言是否需要像和 Java 一样的注解支持呢?
欢迎在评论区交流和讨论!
本文转载自公众号脑子进煎鱼了,如需转载请点击下方联系作者。
关注煎鱼,吸取他的知识
假如给Go语言加上注解,程序会变怎样?相关推荐
- Java语言使用注解处理器生成代码——第三部分:生成源代码
原文作者:deors 原文地址:https://deors.wordpress.com/2011/10/31/annotation-generators/ 译文作者:Jianan - qinxiand ...
- c语言的程序灵魂是什么,C语言 第二章 程序的灵魂--算法
<C语言 第二章 程序的灵魂--算法>由会员分享,可在线阅读,更多相关<C语言 第二章 程序的灵魂--算法(39页珍藏版)>请在人人文库网上搜索. 1.第二章 程序的灵魂-算法 ...
- 常用c语言小程序,c语言经典小程序汇总大全
网上有很多的人说编程有多么多么无聊,其实:不要管别人怎么说,别人说什么,做你自己喜欢做的事就好.坚持下来,你会发现编程的乐趣的.当然,如果你觉得学习编程语言很痛苦,坚持了一段时间后无果,南无果断放弃未 ...
- c语言笔记——黑马程序员上课笔记
C语言概述 1.1 什么是C语言 一提到语言这个词语,自然会想到的是像英语.汉语等这样的自然语言,因为它是人和人交换信息不可缺少的工具. 而今天计算机遍布了我们生活的每一个角落,除了人和人的相互交流之 ...
- 都2023年了,你如果还不知道这18个C语言入门经典程序就亏了
作为一个C语言初学者,如何学代码很重要!俗话说得好,当我刷完每一年的题,就没有我不会的题了,而C语言不需要这么麻烦,他需要记得东西其实不多,基本是哪个就是几个常见的语句加上一些关键字而已.你所看那些大 ...
- 易语言写的程序如何加密防止别人破解
1.花指令的插入,这当然是有必要的,有人说加了花指令没有什么用,现在的反编译软件基本上都有去除花指令的功能,但是难道它能去我就不加了?给破解者增加一点麻烦事也是好的嘛! 2.加壳,现在的很多壳都有自动 ...
- c语言通讯录二分查找,C语言程序设计 通讯录程序.doc
<C语言程序设计 通讯录程序.doc>由会员分享,可在线阅读,更多相关<C语言程序设计 通讯录程序.doc(28页珍藏版)>请在人人文库网上搜索. 1.目录:课 程 设 计 任 ...
- python输入一个正整数n求下列算式的值_C语言编写程序:输入一个正整数x和一个正整数n,求下列算式的值。,C语言 编写一个程序,输入一个正整数,求出它是几位数。...
导航:网站首页 > C语言编写程序:输入一个正整数x和一个正整数n,求下列算式的值.,C语言 编写一个程序,输入一个正整数,求出它是几位数. C语言编写程序:输入一个正整数x和一个正整数n,求下 ...
- 开发语音录入_语言翻译小程序app开发 解决了人们的语言障碍问题
随着经济的发展,人们经济水平的提高,促进了国际交流越来越频繁,人们出国的次数也是越来越多.但是语言交流也是日常的障碍,给诸多的人带来不便.出国旅游要是语言不通还会影响旅游质量.语言翻译小程序的开发,便 ...
最新文章
- 【ZooKeeper】配置文件详解
- ERP实施成功与否,企业文化是致命因素?
- 百度代码规范 -- PHP
- 免费的SEO工具软件大全
- Android UI之ImageView
- 辗转相除最小公倍数的递归求法
- javafx 自定义控件_JavaFX自定义控件– Nest Thermostat第1部分
- CS231n Convolutional Neural Networks for Visual Recognition------Numpy Tutorial
- Apache beam其他学习记录
- freecplus框架-日期、时间和计时器
- IIS搭配Server-u构建企业空间服务(二)
- Struts 1.x 的工作原理
- 狮子鱼社区团购独立版安装方法
- 非平衡电桥电阻计算_用非平衡电桥测量电阻
- RGB888和RGB565颜色对照表
- 2003迁移2008R2难点分析
- 迅雷iOS端安装 - iPhone安装手机迅雷
- Wex5打包报错的解决办法
- 辣椒疫霉RXLR效应子抑制植物免疫
- 成长中必知的20个故事[转]
热门文章
- 史上最快、最强大的Gradle 5.0发布,新特性全解
- 【Android】日常问题记录
- ArcGIS Server 10.1发布结果地图服务——与10.0的区别及过程
- Java数据库驱动链接大全
- react-native ListView 封装 实现 下拉刷新/上拉加载更多
- 基于React的全屏滑动插件react-fullslip
- C#将DLL嵌入到exe当中
- 【原创】MySQL里求给定的时间是所在月份的第几个礼拜
- Android ContentProvider的介绍(很详细)
- 配置gitlab环境实现代码管理及Web Hook测试和ldap认证