DevopsCamp 第一期作业: 《cobra - 02 配置文件的读取与写入(简单)》 解题答案
DevopsCamp 第一期作业: 《cobra - 02 配置文件的读取与写入(简单)》 解题答案
原文链接: https://tangx.in/posts/2023/01/24/devopscamp-cobra-binding-config-file/
本文为 DevOpsCamp 实战训练作业 cobra - 02 配置文件的读取与写入(简单) 的解题答案
DevoOpsCamp 作业地址: https://www.devopscamp.cc/semi-plan-202301-2/posts/homework/cobra02/

作业要求
- 使用 https://github.com/spf13/cobra 实现命令工具
- 命令具有以下参数
--config,-c配置文件
配置文件如下
| |
- 将配置文件保存为
JSON格式
| |
输出结果
| |
单个参数绑定的困境
之前我们使用了 单个参数独立绑定 的方式, 为我们的 greeting 应用绑定了 name 和 age 参数。
这种方式有个很明显的缺点, 如果应用参数的数量较多(比如说几十个) 的时候, 就会出现庞大的参数列表, 可读性 和 维护性 都会变得很差。
| |
因此在生产中, 我们常常会选择 配置 文件来进行 参数/变量 的管理。 例如作业要求中提到的 YAML 或者 JSON 文件。
配置文件
最常用 的的配置文件类型就是 YAML 和 JSON。 除此之外还有 toml, xml, ini 等, 这些类型的配置文件可以在实际碰到的时候去学习掌握, 大差不差。
通常 解析 和 映射 方法名称分别为 Marshal 和 Unmarshal
Marshal(v any) ([]byte, error)将结构体 解析 成[]byte类型。Unmarshal(data []byte, v any) error将[]byte映射 到结构体中。 这里的v需要是 指针类型
但有些库在名字上可能具有一定变种,通常也有迹可循。
MarshalJSON
MarshalYAMl
不同库 对应的的 方法名称 和 实现逻辑 也不尽相同, 如果凭经验使用遇到了问题, 一定要去看看官网文档。
最基本常用的解析库
json:encoding/jsonyaml:gopkg.in/yaml.v3,gopkg.in/yaml.v2v2 和 v3 有区别, 自己研究。
解题过程
1. 指定配置文件参数
由于我们的实际 参数/变量 通过配置文件管理了, 因此我们就需要指定一个配置文件参数。
| |
有了上一篇作业的经验, 这个应该就很简单。
2. 读取配置
我们定义了一个名为 Person 的结构体, 包含两个字段 Name 和 Age, 用于接受参数/变量。
| |
我们在字段后面, 使用 tag 进行了信息补充, 提供 yaml 解析的行为参数。

图片是之前 struct 的截图, 其中
- (1) 是字段名称
- (2-4) 是
tag内容。- (2) 是
tag name, 解析库依赖此字段进行判定。 - (3-4) 是
tag value, 本质上是 字符串。 例如这里name和omitempty使用 分隔符,进行分割。 不同的库的分隔符有所不同, 例如gorm使用的 分号;。 - (3) 在这里对应的是 映射 的字段名称。 例如 yaml 文件中的
name对应结构体中的Name。 这里name也可以是其他值, 例如MyName, 那么就会在 yaml文件中找对应的 MyName 字段。 - (4)
omitempty是 yaml 支持的操作符, 同时还支持flow, inline。 具体功能描述可以参考 https://pkg.go.dev/gopkg.in/yaml.v3#pkg-functions
- (2) 是
| |
- 初始化
person指针对象, 其底层类型为 Person 结构体。 - 在
readConfig函数中, 我们使用os.ReadFile读取文件内容。 - 并通过
yaml.Unmarshal将数据映射到person实例中。 需要 注意的是,person所在的参数未知, 必须是 指针 对象, 否则反射无法保存数据到 内存 中。
保存文件为 json
把配置信息保存为 json 文件, 就是之前 yaml 的反操作。
| |
- 使用
json.Marshal将对象转换成 []byte。 由于是 读取操作,person所在的参数为止可以是结构体, 也可以是指针。 - 使用
os.WriteFile进行文件写入操作。 需要注意的是os.ModePerm这个权限, 对于文件夹是 755, 对于文件是 644, 非常的灵活。
| |
执行后,得到的结果与期望的结果有一点点不同。注意 ,这里的 Name 和 Age 都是大写。
我们对 Person 结构体稍微做一点改造
| |
加上 json tag 之后, 得到的结果就与期望一致了。
| |
思考题
留一点思考题吧。
- 为什么没有设置
json tag也可以成功保存 json 配置? - 设置了
json tag之后, json 配置中的字段名字变了, 他们的优先级是什么? - 要怎么 忽略 一个字段?
答案在官方文档中。
B站作业视频演示
- 原文链接:https://typonotes.com/posts/2023/01/24/devopscamp-cobra-binding-config-file/
- 本文为原创文章,转载注明出处。
- 欢迎 扫码关注公众号
Go与云原生或 订阅网站 https://typonotes.com/ 。 - 第一时间看后续精彩文章。觉得好的话,请猛击文章右下角「在看」,感谢支持。


