Protobuf

141 阅读2分钟

简介

Protobuf 是一种序列化结构化数据的方法,它对于服务之间的通信或存储数据特别有用。 它是谷歌在2001年初设计的(但直到2008年才公开发布),比XML更小、更快。Protobuf消息被序列化成二进制连接格式,非常紧凑,提高了性能。

本文主旨主要介绍 message 的定义

数据的结构是消息,包含一系列的 键值对 的字段。

数据类型如下:

.protoNotesC++Java/KotlinPythonGoRubyC#Php
boolboolbooleanboolboolTrueClass/FalseClassboolboolean
stringstringstringstr/unicodestringString(UTF-8)stringstring
bytesstringByteStringstr(py2) / bytes(py3)[]byteString (ASCII-8BIT)ByteStringstring
doubledoubledoublefloatfloat64Floatdoublefloat
floatfloatfloatfloatfloat32Floatfloatfloat
int32int32intintint32Fixnum or Bignum (as required)intinteger
int64int64longint/longint64Bignumlonginteger/string
uint32uint32intint/longuint32Fixnum or Bignum (as required)uintinteger
uint64uint64intint/longuint64Bignumulonginteger/string
sint32int32intintint32Fixnum or Bignum (as required)intinteger
sint64int64longint/longint64Bignumlong
fixed32uint32intint/longuint32Fixnum or Bignum (as required)uintinteger/string
fixed64uint64longint/longuint64Bignumulonginteger
sfixed32int32intintint32Fixnum or Bignum (as required)intinteger
sfixed64int64longint/longint64Bignumlonginteger/string

Message 定义

我们构建了一个 SearchRequestSearchResponseResult messages。

里面定义了 枚举,重复字段。

syntax = "proto3";

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
  enum Corpus {
    UNIVERSAL = 0;
    WEB = 1;
    IMAGES = 2;
    LOCAL = 3;
    NEWS = 4;
    PRODUCTS = 5;
    VIDEO = 6;
  }
  Corpus corpus = 4;
}

message SearchResponse {
 repeated Result results = 1;
}

message Result {
  string url = 1;
  string title = 2;
  repeated string snippets = 3;
}

说明:

  • string,默认值是 空 string
  • bytes,默认值是 空 bytes
  • bool,默认值是 false
  • 数值类型,默认值是 0
  • 枚举,默认值是 第一个定义的枚举值,它必须是 0
  • 重复字段,空列表

Message 进阶

Any

Any 类型包含一个需要指定类型的任意的序列化消息。如需使用,则需要导入 import google/protobuf/any.proto

syntax = "proto3";

import "google/protobuf/any.proto";

message ErrorStatus {
  string message = 1;
  repeated google.protobuf.Any details = 2;
}

One-Of

如果消息包含多个字段,但是字段同一时间最多只允许一个被设置,可以通过 oneof 实现。

syntax = "proto3";

message SampleMessage {
  oneof test_oneof {
    string name = 1;
    int32 age = 2;
  }
}

Map

Map 可以定义 key, value 的数据集。 例如:map<key_type, value_type> map_field = N;

map<string, Project> projects = 3;