j
首先请看一下 kubernetes core 的 API 代码:https://github.com/kubernetes/api/blob/master/core/v1/types.go
我们可以发现,只要是 optional
的字段,那么必然是一个 pointer:
再比如:
这是为什么呢?
其实在 kubernetes 官方给出的 API 规约中,有这样一句话:https://github.com/kubernetes/community/blob/2e3d491ca40d05233362b125a0e756ad3223a51f/contributors/devel/sig-architecture/api-conventions.md?plain=1#L744
Therefore, we ask that pointers always be used with optional fields that do not have a built-in
nil
value.
翻译为:
我们要求没有内建nil
值的 optional 字段,总是使用 pointers.
首先我们需要了解使用 pointer 和没有使用 pointer 的区别,假设我们没有使用 pointer:
当我们想创建一个 “没有苹果的树”, 我们使用 put 如下 json:
但是由于apple
字段并不是 pointer,所以我们最终创建的是一个空结构体,最终存储(在 etcd 或者 disk)的结构为:
但是这个结构也可以表示一个“有苹果的树”,只不过苹果的名字为“”(空字符串)。
此时,“零值(zero value)”和“空(nil)”之间就有了歧义。 虽然我们可以在代码中添加一些规则来消除这种歧义,比如: 禁止创建名字为空字符串的苹果。但是 Kubernetes API 规约中,也给出了 3 点原因,解释我们为什么最好在 field 是 optional 的情况下,使用 pointer:
此类情况很多,实现者每一个都需要甄别和处理的话,过于劳心费神。
即使指定了
omitempty
,编码器输出也不会省略结构,最后看起来就会乱糟糟的。如果在客户端代码中使用 go 编码,且遵守了“optional->pointer”的规则,那么当遇到一个 pointer 的时候,我们也直接可以反推出这个 field 是 optinal 的,十分方便。
综上所述,如果你也觉得这条规范有道理的话,那么未来在编写或升级 API 的时候,遇到 optional 的时间,第一时间使用 pointer 吧!
版权声明: 本文为 InfoQ 作者【薛zhao君】的原创文章。
原文链接:【http://xie.infoq.cn/article/e723867c421618999e108a893】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论