首先请看一下 kubernetes core 的 API 代码:https://github.com/kubernetes…
咱们能够发现,只有是 optional
的字段,那么必然是一个 pointer:
// nfs represents an NFS mount on the host that shares a pod's lifetime
// More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs
// +optional
NFS *NFSVolumeSource `json:"nfs,omitempty" protobuf:"bytes,7,opt,name=nfs"`
再比方:
// volumeMode defines if a volume is intended to be used with a formatted filesystem
// or to remain in raw block state. Value of Filesystem is implied when not included in spec.
// +optional
VolumeMode *PersistentVolumeMode `json:"volumeMode,omitempty" protobuf:"bytes,8,opt,name=volumeMode,casttype=PersistentVolumeMode"`
这是为什么呢?
其实在 kubernetes 官网给出的 API 规约中,有这样一句话:https://github.com/kubernetes…
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:
type Apple struct {
// +required
Name string `json:"name"`
}
type Tree struct {
// +optional
Apple Apple `json:"apple"`
}
当咱们想创立一个“没有苹果的树”,咱们应用 put 如下 json:
{}
然而因为 apple
字段并不是 pointer,所以咱们最终创立的是一个空构造体,最终存储 (在 etcd 或者 disk) 的构造为:
{
apple: {name: ""}
}
然而这个构造也能够示意一个“有苹果的树”,只不过苹果的名字为“”(空字符串)。
此时,“零值(zero value)”和“空(nil)”之间就有了歧义 。尽管咱们能够在代码中增加一些规定来打消这种歧义,比方:禁止创立名字为空字符串的苹果。
然而 Kubernetes API 规约中,也给出了 3 点起因,解释咱们为什么最好在 field 是 optional 的状况下,应用 pointer:
- 此类情况很多,实现者每一个都须要甄别和解决的话,过于劳心劳神。
- 即便指定了
omitempty
,编码器输入也不会省略构造,最初看起来就会乱哄哄的。 - 如果在客户端代码中应用 go 编码,且恪守了“optional->pointer”的规定,那么当遇到一个 pointer 的时候,咱们也间接能够反推出这个 field 是 optinal 的,非常不便。
综上所述,如果你也感觉这条标准有情理的话,那么将来在编写或降级 API 的时候,遇到 optional 的工夫,第一工夫应用 pointer 吧!