go - 转换为多个匿名接口(interface)是否等同于类型切换?

标签 go interface type-conversion type-switch

我继承了一些看起来像这样的代码:

type FooWrapper struct {
    Stuffer   interface{ GetStuff() *grpc.Stuff }
    Thinger   interface{ GetThing() *grpc.Thing }
    Widgeter  interface{ GetWidget() *grpc.Widget }
    // many more like these
}

func NewFooWrapper(v proto.Message) FooWrapper {
    var w FooWrapper
    w.Stuffer, _ = v.(interface{ GetStuff() *grpc.Stuff })
    w.Thinger, _ = v.(interface{ GetThing() *grpc.Thing })
    w.Widgeter, _ = v.(interface{ GetWidget() *grpc.Widget })
    // many more like these
    return w
}

func (w FooWrapper) GetStuff() *grpc.Stuff {
    if w.Stuffer == nil {
        return nil
    }
    return w.Stuffer.GetStuff()
}

// many more methods like this one
我们可以看到这段代码做了以下事情:
  • 它声明了 FooWrapper带有一堆匿名接口(interface)字段的结构体,每个方法一个可能存在于 proto.Message 的任何实现中.
  • NewFooWrapper构造函数正在转换 v到这些匿名接口(interface)类型中的每一种,丢弃错误。因此,如果 v 中的类型被装箱没有 GetXXX方法,相关字段在w将只是 nil
  • FooWrapper getter 检查对应的字段是否为 nil如果不是,它会调用装箱值的方法。

  • 对我来说,这似乎是实现类型切换的一种非常冗长的方式,尽管我不确定这是惯用的 Go 代码。
    但是我想它在 v 的情况下可能很有用。必须传递给多个不相关的方法,导致类型切换被复制粘贴到任何地方(这不是我在这里得到的代码的情况)。
    实际上,此代码是否等效于类型开关?
    使用这种模式而不是类型开关有什么好处?

    最佳答案

    一句话,“不”,这不是惯用语。但这当然并不意味着它是“错误的”。
    尽管考虑到匿名接口(interface)类型是重复的,但这样做似乎很愚蠢,而不是命名类型。
    如果我继承了该代码,我会立即更改它。
    考虑到确切的代码示例,我还将重新定义我的结构以使用嵌入式接口(interface):

    type Stuffer  interface { GetStuff() *grpc.Stuff }
    type Thinger  interface { GetThing() *grpc.Thing }
    type Widgeter interface { GetWidget() *grpc.Widget }
    
    type FooWrapper struct {
        Stuffer
        Thinger
        Widgeter
        // many more like these
    }
    

    关于go - 转换为多个匿名接口(interface)是否等同于类型切换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62660024/

    相关文章:

    multithreading - 多个 goroutine 会同时调用 Conn 上的方法吗?

    java - 为分层实体设计界面

    c - 如何在 C 中将 unsigned int 值打印为时间字符串

    type-conversion - OCaml 中的类型化整型常量

    reactjs - HTTP 响应中缺少 Content-Range header 。 react 管理员。 Go 语言 API

    go - 如何在 Go 模板中转义 “{{” 和 “}}” 分隔符?

    go - 连接超时访问外部IP google compute engine

    c# - 从具有相同方法签名的多个接口(interface)继承的类

    java - 将数据分块同步到服务器会导致 StackoverflowException

    c++ - 我在 myprogramminglab 中收到错误 "stoi is not a member of std"