转换为多个匿名接口是否等同于类型切换?

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


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

我们可以看到这段代码做了以下事情:

  1. 它声明了一个FooWrapper带有一堆匿名接口字段的结构,每个接口字段对应一个可能存在于任何实现中的方法proto.Message

  2. NewFooWrapper构造函数正在转换v为这些匿名接口类型中的每一种,从而丢弃错误。因此,如果框入的类型v没有GetXXX方法,则相关字段w将简单地为nil

  3. FooWrappergetter 检查相应的字段是否存在nil,如果不是,它会调用装箱值的方法。

对我来说,这似乎是实现类型切换的一种非常冗长的方式,尽管我不确定这是惯用的 Go 代码。

但是我想它在必须传递给多个不相关的方法的情况下可能很有用v,导致类型切换被复制粘贴到任何地方(这不是我在这里得到的代码的情况)。

实际上,此代码是否等效于类型开关?

使用这种模式而不是类型开关有什么好处?


慕运维8079593
浏览 105回答 1
1回答

繁星coding

一句话,“不”,这不是惯用语。但这当然并不意味着它是“错误的”。尽管考虑到匿名接口类型是重复的,但这样做似乎很愚蠢,而不是命名类型。如果我继承了该代码,我会立即更改它。考虑到确切的代码示例,我还将重新定义我的结构以使用嵌入式接口: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}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go