【编辑推荐】
- 几款对象神器,高效力助你走上人生巅峰
- jvm系列(七):jvm调优-对象篇
- Dataset基于SQLAlchemy的便利对象
- Facebook 开源赞助开辟者祛除最固执的软件 bug 的对象
- Python对象箱 | 手把手教你若何强行与良久不愫系的同伙制造话题
沙龙晃荡 | 去哪儿、陌陌、ThoughtWorks在主动化运维中的实践!10.28不见不散!
我以前构建过一个对象,以让生活更轻松。这个对象被称为: gomodifytags ,它会根据字段名称主动填充构造体的标签字段。示例如下:
(在 vim-go 中应用 gomodifytags 的一个用轨典范)
应用如许的对象可以 轻松治理 构造体的多个字段。该对象还可以添加和删除标签,治理标签选项(如omitempty),定义转换规矩(snake_case、camelCase 等)等等。然则这个对象是若何工作的? 在后台中它毕竟应用了哪些 Go 包? 有很多如许的问题须要答复。
这是一篇异常长的博客文┞仿,说清楚明了若何编写类似如许的对象以及若何构建它的每一个细节。 它包含很多特有的细节、提示和技能和某些未知的 Go 位。
解析函数只完成了一件事。解析源码并返回一个ast.Node。如不雅我们仅传递文件,这是异常简单的,在这种情况下,我们应用parser.ParseFile()函数。须要留意的是token.NewFileSet(),它创建一个类型为*token.FileSet。我们将它存储在c.fset中,但也传递给parser.ParseFile()函数。为什么呢?
拿一杯咖啡,开端深刻商量吧!
起首,列出这个对象须要完成的功能:
- 它须要攫取源文件,懂得并可以或许解析 Go 文件
- 它须要找到相干的构造体
- 找到构造体后,须要获取其字段名称
- 它须要根据字段名更新构造标签(根据转换规矩,即:snake_case)
- 它须要可以或许应用这些修改来更新文件,或者可以或许以可接收的方法输出修改
构造标签的定义比较简洁所以不轻易懂得。该定义可以分化如下:
- 构造标签是一个字符串(字符串类型)
- 构造标签的 Key 长短引号字符串
- 构造标签的 value 是一个带引号的字符串
- 构造标签的 key 和 value 用冒号(:)分隔。冒号隔开的一个 key 和对应的 value 称为 “key value 对”。
- 一个构造标签可以包含多个 key valued 对(可选)。key-value 对之间用空格隔开。
- 可选设置不属于定义的一部分。类似 encoding/json 包将 value 解析为逗号分开的列表。value 的第一个逗号后面的任何部分都是可选设置的一部分,例如:“ foo, omitempty,string”。个中 value 拥有一个叫 “foo” 的名字和可选设置 [“omitempty”, "string"]
- 因为构造标签是一个字符串,须要双引号或者反引号包含。又因为 value 也须要引号包含,经常用反引号包含构造标签。
以上规矩概况如下:
(构造标签的定义有很多隐含细节)
已经懂得什么是构造标签,接下来可以根据须要修改构造标签。问题来了,若何才能很轻易的对所做的修改进行解析?很荣幸,reflect.StructTag 包含一个可以解析构造标签并返回特定 key 的 value 的办法。示例如下:
- package main
- import (
- "fmt"
- "reflect"
- )
- func main() {
- tag := reflect.StructTag(`species:"gopher" color:"blue"`)
- fmt.Println(tag.Get("color"), tag.Get("species"))
- }
输出:
- blue gopher
如不雅 key 不存在则返回空串。
这是异常有赞助的, 然则 ,它有一些附加解释,使其不合适我们,因为我们须要更多的灵活性。这些是:
- 它无法检测到标签是否存在 格局缺点 (即:键被引用了,值是未引用等)
- 它不知道选项的 语义
- 它没有办法 迭代现有的标签 或返回它们。 我们必须知道我们要修改哪些标签。 如不雅不知道其名字怎么办?
- 修改现有标签是弗成能的。
推荐阅读
前人有云,“一言既出,驷马难追”,可见对说出口的话,是多么看重。可是,人总有说错话的时刻啊!为懂得决“手滑”的懊末路,微信在5.3.1.16版本中上线了“微信撤回”的>>>详细阅读
本文标题:用Go语言编写一门工具的终极指南
地址:http://www.17bianji.com/lsqh/38247.html
1/2 1