来自我的包外部的结构的多态性

我正在尝试构建一个方法,该方法使用 Kubernetes 客户端 go 库,获取并返回给定 .我有这个:*metav1.OwnerReference


func fetchResource(ref *metav1.OwnerReference, options *RequestOptions) (*metav1.ObjectMeta, error) {

    switch ref.Kind {

    case "ReplicaSet":

        return options.Clientset.AppsV1().ReplicaSets(options.Namespace).Get(options.Context, ref.Name, metav1.GetOptions{})

    case "Deployment":

        return options.Clientset.AppsV1().Deployments(options.Namespace).Get(options.Context, ref.Name, metav1.GetOptions{})

    case "Job":

        fallthrough

    // more stuff...

    default:

        return nil, nil

    }

}

此代码无法编译,因为:


不能使用选项。Clientset.AppsV1().ReplicaSets(选项。命名空间)。获取(选项。上下文,引用。名称, (元 v1.获取选项文本))(类型为 *“k8s.io/api/apps/v1”的值。副本集) 为 *“k8s.io/apimachinery/pkg/apis/meta/v1”。返回语句中的对象Meta值


我的猜测是,由于文档说基本上所有资源都嵌入了 ,我可以将其用作返回类型。metav1.ObjectMeta


我尝试创建并返回一个,但意识到我无法为包外的类型实现它:interface


type K8sResource interface {

    Name() string

    Kind() string

    OwnerReferences() []metav1.OwnerReference

}


func (pod *corev1.Pod) Name() string {

    return pod.Name

}

func (pod *corev1.Pod) Kind() string {

    return pod.Kind

}

func (pod *corev1.Pod) OwnerReferences() []metav1.OwnerReference {

    return pod.OwnerReferences

}

此代码无法编译,因为:


无效的接收器 *“k8s.io/api/core/v1”。Pod(此包中未定义的类型)


这里的惯用和正确的解决方案是什么?


沧海一幻觉
浏览 92回答 1
1回答

慕工程0101907

如果要将导入的类型作为接口返回,而这些类型尚未实现,则可以将它们包装在实现它的类型中。例如:type K8sResource interface {    Name() string    Kind() string    OwnerReferences() []metav1.OwnerReference}type replicaSet struct{ *v1.ReplicaSet }func (s replicaSet) Name() string {    return s.ReplicaSet.Name}func (s replicaSet) Kind() string {    return s.ReplicaSet.Kind}func (s replicaSet) OwnerReferences() []metav1.OwnerReference {    return s.ReplicaSet.OwnerReferences}func fetchResource(ref *metav1.OwnerReference, options *RequestOptions) (K8sResource, error) {    switch ref.Kind {    case "ReplicaSet":        res, err := options.Clientset.AppsV1().ReplicaSets(options.Namespace).Get(options.Context, ref.Name, metav1.GetOptions{})        if err != nil {            return nil, err        }        return replicaSet{res}, nil // wrap it up    case "Pod":        res, err := options.Clientset.AppsV1().Pods(options.Namespace).Get(options.Context, ref.Name, metav1.GetOptions{})        if err != nil {            return nil, err        }        return pod{res}, nil // wrap it up    case "Job":        fallthrough    // more stuff...    default:        return nil, nil    }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go