乐趣区

关于kubernetes:Kubernetes-API规范为optional的字段使用pointer

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

退出移动版