ProtoMessage 方法的目的是啥?
Posted
技术标签:
【中文标题】ProtoMessage 方法的目的是啥?【英文标题】:What's the purpose of ProtoMessage method?ProtoMessage 方法的目的是什么? 【发布时间】:2017-12-17 16:48:49 【问题描述】:当我从协议缓冲区文件生成 go 代码时,我注意到生成的每个结构都实现了 Message 接口,https://github.com/golang/protobuf/blob/master/proto/lib.go#L277
有关生成的代码示例,请参阅https://github.com/google/go-genproto/blob/master/googleapis/rpc/status/status.pb.go#L97
显然,Message 接口上的其他方法 String() 和 Reset() 有一个明显的目的,具体的实现示例说明了这一点。但是,我不明白 ProtoMessage() 方法的目的。该方法不带参数也不返回参数,那为什么会存在呢?
【问题讨论】:
猜测(因此为什么这是评论,而不是答案),我会说这是为了确保您不会意外实现 Message 接口。只有String
和Reset
方法,太多的东西会匹配。例如:如果不需要ProtoMessage()
,bytes.Buffer
将实现接口。
【参考方案1】:
引用官方文档:Protocol Buffers: Go Generated Code:
给定一个简单的消息声明:
message Foo
protocol buffer 编译器生成一个名为
Foo
的结构。*Foo
实现了 Message 接口。有关详细信息,请参阅内联 cmets。type Foo struct // Reset sets the proto's state to default values. func (m *Foo) Reset() *m = Foo // String returns a string representation of the proto. func (m *Foo) String() string return proto.CompactTextString(m) // ProtoMessage acts as a tag to make sure no one accidentally implements the // proto.Message interface. func (*Foo) ProtoMessage()
请注意,所有这些成员都始终存在;
optimize_for
选项不会影响 Go 代码生成器的输出。
这是 Go 官方 FAQ: How can I guarantee my type satisfies an interface? 中描述的(类似)技术
如果您希望接口的用户明确声明他们实现了该接口,您可以将具有描述性名称的方法添加到接口的方法集中。例如:
type Fooer interface Foo() ImplementsFooer()
然后类型必须实现
ImplementsFooer
方法成为Fooer
,清楚地记录事实并在godoc 的输出中宣布它。type Bar struct func (b Bar) ImplementsFooer() func (b Bar) Foo()
大多数代码都没有使用这些约束,因为它们限制了界面思想的实用性。但有时,它们对于解决相似接口之间的歧义是必要的。
所以ProtoMessage()
方法基本上有2个用途:
proto.Message
接口但不是“真实的” protobuf 消息值:
它还记录了类型是(实现)ProtoMessage 充当一个标签,以确保没有人意外实现 proto.Message 接口。
Message
的事实。起初这可能没有真正的价值,因为代码是生成的,你不应该为它费心,但代码分析器和 Go IDE 可能会很好地利用它;它也出现在生成的文档中。
【讨论】:
以上是关于ProtoMessage 方法的目的是啥?的主要内容,如果未能解决你的问题,请参考以下文章
AuthorizationServerSecurityConfigurer 中的领域方法的目的是啥?
EAAccessoryDelegate 中的 –accessoryDidDisconnect: 方法的目的是啥?