thu*_*urt 8 go protocol-buffers
当我从协议缓冲区文件生成 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() 方法的目的。该方法不接受任何参数,也不返回任何参数,那么为什么会出现这种情况呢?
引自官方文档:Protocol Buffers: Go Generated Code:
给定一个简单的消息声明:
Run Code Online (Sandbox Code Playgroud)message Foo {}协议缓冲区编译器生成一个名为
Foo. A*Foo实现了Message接口。有关更多信息,请参阅内嵌注释。Run Code Online (Sandbox Code Playgroud)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 官方常见问题解答中描述的(类似)技术:如何保证我的类型满足接口?
如果您希望接口的用户明确声明他们实现了它,您可以将具有描述性名称的方法添加到接口的方法集中。例如:
Run Code Online (Sandbox Code Playgroud)type Fooer interface { Foo() ImplementsFooer() }然后,类型必须将
ImplementsFooer方法实现为 aFooer,清楚地记录事实并在godoc的输出中宣布它。Run Code Online (Sandbox Code Playgroud)type Bar struct{} func (b Bar) ImplementsFooer() {} func (b Bar) Foo() {}大多数代码不使用这种约束,因为它们限制了接口思想的效用。但有时,它们对于解决相似接口之间的歧义是必要的。
所以这个ProtoMessage()方法基本上有两个目的:
proto.Message接口但不是“真正的”protobuf 消息值:
ProtoMessage 作为一个标签来确保没有人意外地实现了 proto.Message 接口。
Message。刚开始生成代码时,这可能没有真正的价值,您不应该过多打扰它,但是代码分析器和 Go IDE 可能会很好地利用它;它也出现在生成的文档中。| 归档时间: |
|
| 查看次数: |
2694 次 |
| 最近记录: |