首先请看一下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吧!