【问题标题】:Type assertion with embeded types嵌入类型的类型断言
【发布时间】:2018-11-19 09:13:00
【问题描述】:
type BizError struct {
    Code string
    Mesg string
}

type ApiReply struct {
    Err BizError
}

type GetDataReply struct {
    Data interface{}
    ApiReply
}

有了上面的定义,我想做以下事情:

func Func1(data interface{}) {
    switch data.(type) {
    case ApiReply:
        data.(ApiReply).Err.Code = "0"
    }
}

关键问题是在 Func1 中,类型开关知道嵌入 ApiReply 的任何新类型,它是一个“通用”处理程序。而data 传递给它的实际上是 ApiReply 的“子类”。显然,在 Go 中,您不能将 GetDataReply 类型断言到 ApiReply。

我该如何处理这种情况,以便在 Func1 中我不需要明确声明所有可能嵌入 ApiReply 的结构?

【问题讨论】:

标签: go type-assertion


【解决方案1】:

您正在尝试在 go 中实现继承样式系统。结构嵌入不是继承,不应被视为或视为继承。这是 Go 中的一种反模式,通常不会像您希望或期望的那样工作。

相反,更惯用的方法是定义一个接口(或几个接口)并让您的响应类型实现符合要求的必要方法。

type ApiReply interface {
    Status() (string, string)

    Body() (io.Reader, error)
}

type BizError struct {
    Code string
    Mesg string
}

func (b BizError) Status() (string, string) {
    return b.Code, b.Mesg
}

func (b BizError) Body() (io.Reader, error) {
    return nil, errors.New("BizError never contains a body")
}

然后您将在其他响应类型结构上实现ApiReply。我当然是在猜测您在这里实际需要什么,但希望这能说明问题。

如果你发现你必须这样做,你现在可以对你收到的 ApiReply 实例进行类型切换,如果绝对必要,特殊情况下任何基础类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-10
    • 2018-03-08
    • 2019-08-31
    • 1970-01-01
    • 2014-01-22
    • 1970-01-01
    • 1970-01-01
    • 2014-01-08
    相关资源
    最近更新 更多