我继承了一些看起来像这样的代码:
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
带有一堆匿名接口字段的结构,每个接口字段对应一个可能存在于任何实现中的方法proto.Message
。
NewFooWrapper
构造函数正在转换v
为这些匿名接口类型中的每一种,从而丢弃错误。因此,如果框入的类型v
没有GetXXX
方法,则相关字段w
将简单地为nil
FooWrapper
getter 检查相应的字段是否存在nil
,如果不是,它会调用装箱值的方法。
对我来说,这似乎是实现类型切换的一种非常冗长的方式,尽管我不确定这是惯用的 Go 代码。
但是我想它在必须传递给多个不相关的方法的情况下可能很有用v
,导致类型切换被复制粘贴到任何地方(这不是我在这里得到的代码的情况)。
实际上,此代码是否等效于类型开关?
使用这种模式而不是类型开关有什么好处?
繁星coding
相关分类