Go struct:嵌套多个字段但只能指定一个字段
Go struct: multiple nested fields but only one field can be specified
我想知道如何在 Go 中实现继承。阅读后我明白我必须考虑结构嵌入。因为我是一名 Kubernetes 开发人员,所以我跳转到 Kubernetes 源代码并开始阅读 PodSpec,其中 volumes 字段更接近我正在寻找的内容。
当我以为自己开始理解时,有件事引起了我的兴趣。
通过阅读下面的代码片段,在 type VolumeSource struct
之前,您可以阅读 Only one of its members may be specified
type Volume struct {
// Volume's name.
// Must be a DNS_LABEL and unique within the pod.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
// VolumeSource represents the location and type of the mounted volume.
// If not specified, the Volume is implied to be an EmptyDir.
// This implied behavior is deprecated and will be removed in a future version.
VolumeSource `json:",inline" protobuf:"bytes,2,opt,name=volumeSource"`
}
// Represents the source of a volume to mount.
// Only one of its members may be specified.
type VolumeSource struct {
// HostPath represents a pre-existing file or directory on the host
// machine that is directly exposed to the container. This is generally
// used for system agents or other privileged things that are allowed
// to see the host machine. Most containers will NOT need this.
// More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath
// ---
// TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not
// mount host directories as read/write.
// +optional
HostPath *HostPathVolumeSource `json:"hostPath,omitempty" protobuf:"bytes,1,opt,name=hostPath"`
// EmptyDir represents a temporary directory that shares a pod's lifetime.
// More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir
// +optional
EmptyDir *EmptyDirVolumeSource `json:"emptyDir,omitempty" protobuf:"bytes,2,opt,name=emptyDir"`
// GCEPersistentDisk represents a GCE Disk resource that is attached to a
// kubelet's host machine and then exposed to the pod.
// More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk
// +optional
GCEPersistentDisk *GCEPersistentDiskVolumeSource `json:"gcePersistentDisk,omitempty" protobuf:"bytes,3,opt,name=gcePersistentDisk"`
// AWSElasticBlockStore represents an AWS Disk resource that is attached to a
// kubelet's host machine and then exposed to the pod.
// More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore
// +optional
AWSElasticBlockStore *AWSElasticBlockStoreVolumeSource `json:"awsElasticBlockStore,omitempty" protobuf:"bytes,4,opt,name=awsElasticBlockStore"`
// GitRepo represents a git repository at a particular revision.
// DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an
// EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir
// into the Pod's container.
// +optional
....
如何以及在何处满足此约束条件?
它是在结构定义中编写的还是在另一个 .go 文件的源代码中以编程方式编写的?因为我在源代码中寻找它可以通过编程方式验证它,但我没有看到。
拜托,你能帮我理解一下吗?
language spec 中没有限制结构字段值的东西。但是,我有一种很好的感觉,因为所有字段都是指针,所以卷源方法检查所有字段并期望只有一个字段为非零。
可能是这样的,虽然我不确定 reflect 的用法
func (v VolumeSource) CheckFields() error {
s := reflect.TypeOf(v)
counter := 0
for i:= s.NumField() - 1; i >= 0 ; i-- {
n := s.Field(i).Name()
e := reflect.ValueOf(v).Field(i)
if !e.IsValid(){
continue
}
if e != nil {
counter++
}
if counter > 1{
return errors.New("more than 1 field initialized")
}
}
}
我想知道如何在 Go 中实现继承。阅读后我明白我必须考虑结构嵌入。因为我是一名 Kubernetes 开发人员,所以我跳转到 Kubernetes 源代码并开始阅读 PodSpec,其中 volumes 字段更接近我正在寻找的内容。
当我以为自己开始理解时,有件事引起了我的兴趣。
通过阅读下面的代码片段,在 type VolumeSource struct
之前,您可以阅读 Only one of its members may be specified
type Volume struct {
// Volume's name.
// Must be a DNS_LABEL and unique within the pod.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
// VolumeSource represents the location and type of the mounted volume.
// If not specified, the Volume is implied to be an EmptyDir.
// This implied behavior is deprecated and will be removed in a future version.
VolumeSource `json:",inline" protobuf:"bytes,2,opt,name=volumeSource"`
}
// Represents the source of a volume to mount.
// Only one of its members may be specified.
type VolumeSource struct {
// HostPath represents a pre-existing file or directory on the host
// machine that is directly exposed to the container. This is generally
// used for system agents or other privileged things that are allowed
// to see the host machine. Most containers will NOT need this.
// More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath
// ---
// TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not
// mount host directories as read/write.
// +optional
HostPath *HostPathVolumeSource `json:"hostPath,omitempty" protobuf:"bytes,1,opt,name=hostPath"`
// EmptyDir represents a temporary directory that shares a pod's lifetime.
// More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir
// +optional
EmptyDir *EmptyDirVolumeSource `json:"emptyDir,omitempty" protobuf:"bytes,2,opt,name=emptyDir"`
// GCEPersistentDisk represents a GCE Disk resource that is attached to a
// kubelet's host machine and then exposed to the pod.
// More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk
// +optional
GCEPersistentDisk *GCEPersistentDiskVolumeSource `json:"gcePersistentDisk,omitempty" protobuf:"bytes,3,opt,name=gcePersistentDisk"`
// AWSElasticBlockStore represents an AWS Disk resource that is attached to a
// kubelet's host machine and then exposed to the pod.
// More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore
// +optional
AWSElasticBlockStore *AWSElasticBlockStoreVolumeSource `json:"awsElasticBlockStore,omitempty" protobuf:"bytes,4,opt,name=awsElasticBlockStore"`
// GitRepo represents a git repository at a particular revision.
// DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an
// EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir
// into the Pod's container.
// +optional
....
如何以及在何处满足此约束条件? 它是在结构定义中编写的还是在另一个 .go 文件的源代码中以编程方式编写的?因为我在源代码中寻找它可以通过编程方式验证它,但我没有看到。
拜托,你能帮我理解一下吗?
language spec 中没有限制结构字段值的东西。但是,我有一种很好的感觉,因为所有字段都是指针,所以卷源方法检查所有字段并期望只有一个字段为非零。
可能是这样的,虽然我不确定 reflect 的用法
func (v VolumeSource) CheckFields() error {
s := reflect.TypeOf(v)
counter := 0
for i:= s.NumField() - 1; i >= 0 ; i-- {
n := s.Field(i).Name()
e := reflect.ValueOf(v).Field(i)
if !e.IsValid(){
continue
}
if e != nil {
counter++
}
if counter > 1{
return errors.New("more than 1 field initialized")
}
}
}