ProtoBuf笔记

  • Filed Number:范围 1- 2^29 - 1(536,870,911)排除19000 - 19999(供ProtoBuf内部使用)

  • 用于数据保存时,同一个message中某些字段被删除,如果新增字段使用相同的Filed Number,会和已被删除的字段的Filed Number重复,使用reserved避免此问题

    message Foo {
      reserved 2, 15, 9 to 11;
      reserved "foo", "bar";
    }
  • singular:proto3默认设置,不需要显式设置

  • repeated:使用packed,减少数据量;将数据存储方式由Tag-Value,Tag-Value...变成Tag(WireType=2)-Length(Value总长度)-Value-Value-Value-Value...;proto3默认设置[packed = true],proto2默认没有[packed = true]

  • WireType:5(32-bit),是固定位数,没有msb,用于大于2^28的数据,因为Varint的int32每个字节有一位作为msb,只能存储小于等于2^28的数据,大于2^28用int64,反而占用更多字节;同理1(64-bit),用于大于2^56的数据。

  • 未赋值的字段默认为默认值。

  • 枚举:Proto3枚举类型第一个值必须是0;默认值为0;Proto2默认值为第一个值;

  • 枚举类型可以使用 别名(alias) 定义相同的值;

    enum EnumAllowingAlias {
      option allow_alias = true;
      UNKNOWN = 0;
      STARTED = 1;
      RUNNING = 1;
    }
  • 嵌套类型复用:Message.SubMessage
  • 嵌套message生成代码,增加一个中间类Types
message Foo {
  message Bar {
  }
}
namespace [...]
{
  public sealed partial class Foo : IMessage<Foo>
  {
    public static partial class Types
    {
      public sealed partial class Bar : IMessage<Bar> { ... }
    }
  }
}

 

  • import public

    // new.proto
    // All definitions are moved here
    // old.proto
    // This is the proto that all clients are importing.
    import public "new.proto";
    import "other.proto";
    // client.proto
    import "old.proto";
    // You use definitions from old.proto and new.proto, but not other.proto
  • Oneof:多个字段共享一个内存,其中一个字段被赋值时,其他字段会被清空

  • map类型:对应代码中的Google.Protobuf.Collections.MapField<TKey, TValue>

    map<key_type, value_type> map_field = N;

    key_type: int、string;except:float point、bytes、enum

    value_type:excpet maps

  • 与Map类型等价

    message MapFieldEntry {
      key_type key = 1;
      value_type value = 2;
    }
    
    repeated MapFieldEntry map_field = N;
  • Repeated Fields 对应代码中的Google.Protobuf.Collections.RepeatedField<T>

  • package
    package foo.bar;
    message Open { ... }
    message Foo {
      ...
      foo.bar.Open open = 1;
      ...
    }
  • Any:在messageType中可以使用任意类型,比如代码中自定义类

import "google/protobuf/any.proto";

message ErrorStatus {
  string message = 1;
  repeated google.protobuf.Any details = 2;
}
// Storing an arbitrary message type in Any.
NetworkErrorDetails details = ...;
ErrorStatus status;
status.add_details()->PackFrom(details);

// Reading an arbitrary message from Any.
ErrorStatus status = ...;
for (const Any& detail : status.details()) {
  if (detail.Is<NetworkErrorDetails>()) {
    NetworkErrorDetails network_error;
    detail.UnpackTo(&network_error);
    ... processing network_error ...
  }
}

 

  • Proto中的RPC:
    • c#不支持生成service
service SearchService {
  rpc Search (SearchRequest) returns (SearchResponse);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值