【问题标题】:External packages implementing custom declared interface in Golang在 Golang 中实现自定义声明接口的外部包
【发布时间】:2021-11-02 23:25:00
【问题描述】:

我正在创建一个函数来编组各种 go-client 资源:*v1.Namespace、*v1.Pod 等。 想法是让他们实现一个自定义接口并创建一个函数,其中参数的类型将是我声明的接口:

package kubernetes

import (
    "gopkg.in/yaml.v2"
    v1 "k8s.io/api/core/v1"
)

type Marshalable interface {
    Marshal()
}

func (obj *v1.Namespace) Marshal() {

}

func (obj *v1.Pod) Marshal() {
}

func marshal(obj Marshalable) string {
    y, err := yaml.Marshal(obj)
    if err != nil {
        panic(err)
    }
    return string(y)
}

Marshal() 只是一个空函数,以便类型能够实现接口。但是当然,由于 go-client 资源来自外部包,我不能这样做。有什么建议吗?

【问题讨论】:

  • 你在这里做什么编组? JSON?二进制?
  • 我正在做 JSON 编组。
  • 我无法理解您为什么将问题颠倒过来。 Marshal 接受 any 类型并产生 bytes/strings。不需要对类型进行编组来实现编组功能,除非某些极端情况应尽可能保持偶发性。
  • 这个想法是从其他检索 Kubernetes 对象的地方调用 marshal(obj Marshalable) 函数。我只想拥有一个带有错误处理等功能的marshal(obj Marshable) 函数,并且可以从多个地方调用它。方法Marshal() 只是一个空方法,用于实现Marshable 接口。可能是方法的名字混淆了yaml.Marshal(obj),抱歉。

标签: go generics types interface


【解决方案1】:

你可以在你的包本地创建一个类型定义:

type Namespace v1.Namespace
type Pod v1.Pod

并在这些本地类型上定义方法:

func (obj *Namespace) Marshal() {}
func (obj *Pod) Marshal()       {}

并使用:

var ns  *v1.Namespace
var pod *v1.Pod

(*Namespace)(ns).Marshal()
(*Pod)(pod).Marshal()

那么您的通用 Marshal 函数可能如下所示:

// added error return - as this is standard practice with a marshaler
func Marshal(obj interface{}) ([]byte, error) {

    if v, ok := obj.(*v1.Namespace); ok {
        return (*Namespace)(v).Marshal()
    }

    if v, ok := obj.(*v1.Pod); ok {
        return (*Pod)(v).Marshal()
    }

    return nil, fmt.Errorf("unsupported type: %T", obj)
}

或将您的类型编组逻辑直接移动到上述函数中。

https://play.golang.org/p/vwL-CrtGBRR

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-09
    • 2020-04-22
    • 1970-01-01
    • 2017-11-04
    • 2011-08-03
    相关资源
    最近更新 更多