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

  1. 此类情况很多,实现者每一个都须要甄别和解决的话,过于劳心劳神。
  2. 即便指定了 omitempty,编码器输入也不会省略构造,最初看起来就会乱哄哄的。
  3. 如果在客户端代码中应用go编码,且恪守了“optional->pointer”的规定,那么当遇到一个pointer的时候,咱们也间接能够反推出这个field是optinal的,非常不便。

综上所述,如果你也感觉这条标准有情理的话,那么将来在编写或降级API的时候,遇到optional的工夫,第一工夫应用pointer吧!