dpe77294 2017-12-17 16:48
浏览 156
已采纳

ProtoMessage方法的目的是什么?

when I generate go code from a protocol buffer file, I noticed that each of the generated structs implement the Message interface, https://github.com/golang/protobuf/blob/master/proto/lib.go#L277

For an example of the code that is generated, see https://github.com/google/go-genproto/blob/master/googleapis/rpc/status/status.pb.go#L97

Clearly, the other methods on Message interface, String() and Reset(), have an obvious purpose and the concrete implementation example makes that clear. However, I don't understand the purpose of the ProtoMessage() method. The method takes no parameters and returns no arguments, so why is it there?

  • 写回答

1条回答 默认 最新

  • duangang79177 2017-12-17 18:17
    关注

    Quoting from official doc: Protocol Buffers: Go Generated Code:

    Given a simple message declaration:

    message Foo {}
    

    the protocol buffer compiler generates a struct called Foo. A *Foo implements the Message interface. See the inline comments for more information.

    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()    {}
    

    Note that all of these members are always present; the optimize_for option does not affect the output of the Go code generator.

    This is a (similar) technique described in Go official FAQ: How can I guarantee my type satisfies an interface?

    If you wish the users of an interface to explicitly declare that they implement it, you can add a method with a descriptive name to the interface's method set. For example:

    type Fooer interface {
        Foo()
        ImplementsFooer()
    }
    

    A type must then implement the ImplementsFooer method to be a Fooer, clearly documenting the fact and announcing it in godoc's output.

    type Bar struct{}
    func (b Bar) ImplementsFooer() {}
    func (b Bar) Foo() {}
    

    Most code doesn't make use of such constraints, since they limit the utility of the interface idea. Sometimes, though, they're necessary to resolve ambiguities among similar interfaces.

    So the ProtoMessage() method basically has 2 purposes:

    • The main purpose is as documented in the generated code: to make sure you don't pass a value for protobuf serialization / deserialization which otherwise (without this method) would implement the proto.Message interface but is not a "real" protobuf message value:

      ProtoMessage acts as a tag to make sure no one accidentally implements the proto.Message interface.

    • And it also documents the fact that the type is a (implements) Message. This may not have a real value at first as the code is generated and you should not bother much with it, but code analyzers and Go IDE's may make good use of it; and it also appears in generated docs.
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么