首页 » 网站建设 » phpbigintint技巧_Protobuf3语法详解

phpbigintint技巧_Protobuf3语法详解

访客 2024-11-26 0

扫一扫用手机浏览

文章目录 [+]

syntax = "proto3";message SearchRequest {string query = 1;int32 page_number = 2;int32 result_per_page = 3;}文件的第一行指定了你正在利用proto3语法:如果你没有指定这个,编译器会利用proto2。
这个指定语法行必须是文件的非空非注释的第一个行。
SearchRequest格式有3个字段,在中承载的数据分别对应于每一个字段。
个中每个字段都有一个名字和一种类型。
指定字段类型

在上面的例子中,所有字段都是标量类型:两个整型(page_number和result_per_page),一个string类型(query)。
当然,你也可以为字段指定其他的合成类型,包括列举(enumerations)或其他类型。

分配标识号

正如你所见,在定义中,每个字段都有唯一的一个数字标识符。
这些标识符是用来在的二进制格式中识别各个字段的,一旦开始利用就不能够再改变。
注:[1,15]之内的标识号在编码的时候会占用一个字节。
[16,2047]之内的标识号则占用2个字节。
以是该当为那些频繁涌现的元素保留 [1,15]之内的标识号。
牢记:要为将来有可能添加的、频繁涌现的标识号预留一些标识号。

phpbigintint技巧_Protobuf3语法详解

最小的标识号可以从1开始,最大到2^29 - 1, or 536,870,911。
不可以利用个中的[19000-19999]( (从FieldDescriptor::kFirstReservedNumber 到 FieldDescriptor::kLastReservedNumber))的标识号, Protobuf协议实现中对这些进行了预留。
如果非要在.proto文件中利用这些预留标识号,编译时就会报警。
同样你也不能利用早期保留的标识号。

phpbigintint技巧_Protobuf3语法详解
(图片来自网络侵删)
指定字段规则

所指定的字段润色符必须是如下之一:

singular:一个格式良好的该当有0个或者1个这种字段(但是不能超过1个)。
repeated:在一个格式良好的中,这种字段可以重复任意多次(包括0次)。
重复的值的顺序会被保留。
在proto3中,repeated的标量域默认情形下利用packed。
你可以理解更多的pakced属性在Protocol Buffer 编码添加更多类型

在一个.proto文件中可以定义多个类型。
在定义多个干系的的时候,这一点特殊有用——例如,如果想定义与SearchResponse类型对应的回答格式的话,你可以将它添加到相同的.proto文件中,如:

message SearchRequest {string query = 1;int32 page_number = 2;int32 result_per_page = 3;}message SearchResponse {...}添加注释

向.proto文件添加注释,可以利用C/C++/java风格的双斜杠(//) 语法格式,如:

message SearchRequest {string query = 1;int32 page_number = 2; // Which page number do we want?int32 result_per_page = 3; // Number of results to return per page.}保留标识符(Reserved)

如果你通过删除或者注释所有域,往后的用户可以重用标识号当你重新更新类型的时候。
如果你利用旧版本加载相同的.proto文件这会导致严重的问题,包括数据破坏、隐私缺点等等。
现在有一种确保不会发生这种情形的方法便是指定保留标识符(and/or names, which can also cause issues for JSON serialization不明白什么意思),protocol buffer的编译器会警告未来考试测验利用这些域标识符的用户。

message Foo {reserved 2, 15, 9 to 11;reserved "foo", "bar";}

注:不要在同一行reserved声明中同时声明域名字和标识号

从.proto文件天生了什么?

当用protocol buffer编译器来运行.proto文件时,编译器将天生所选择措辞的代码,这些代码可以操作在.proto文件中定义的类型,包括获取、设置字段值,将序列化到一个输出流中,以及从一个输入流中解析。

对C++来说,编译器会为每个.proto文件天生一个.h文件和一个.cc文件,.proto文件中的每一个有一个对应的类。
对Java来说,编译器为每一个类型天生了一个.java文件,以及一个分外的Builder类(该类是用来创建类接口的)。
对Python来说,有点不太一样——Python编译器为.proto文件中的每个类型天生一个含有静态描述符的模块,,该模块与一个元类(metaclass)在运行时(runtime)被用来创建所需的Python数据访问类。
对go来说,编译器会为每个类型天生了一个.pd.go文件。
对付Ruby来说,编译器会为每个类型天生了一个.rb文件。
javaNano来说,编译器输出类似于java但是没有Builder类对付Objective-C来说,编译器会为每个类型天生了一个pbobjc.h文件和pbobjcm文件,.proto文件中的每一个有一个对应的类。
对付C#来说,编译器会为每个类型天生了一个.cs文件,.proto文件中的每一个有一个对应的类。

你可以从如下的文档链接中获取每种措辞更多API(proto3版本的内容很快就公布)。
API Reference

标量数值类型

一个标量字段可以含有一个如下的类型——该表格展示了定义于.proto文件中的类型,以及与之对应的、在自动天生的访问类中定义的类型:

double doubledoublefloatfloat64Floatdoublefloat

float floatfloatfloatfloat32Floatfloatfloat

int32利用变长编码,对付负值的效率很低,如果你的域有可能有负值,请利用sint64替代int32intintint32Fixnum 或者 Bignum(根据须要)intinteger

uint32利用变长编码uint32intint/longuint32Fixnum 或者 Bignum(根据须要)uintinteger

uint64利用变长编码uint64longint/longuint64Bignumulonginteger/string

sint32利用变长编码,这些编码在负值时比int32高效的多int32intintint32Fixnum 或者 Bignum(根据须要)intinteger

sint64利用变长编码,有符号的整型值。
编码时比常日的int64高效。
int64longint/longint64Bignumlonginteger/string

fixed32总是4个字节,如果数值总是比总是比228大的话,这个类型会比uint32高效。
uint32intintuint32Fixnum 或者 Bignum(根据须要)uintinteger

fixed64总是8个字节,如果数值总是比总是比256大的话,这个类型会比uint64高效。
uint64longint/longuint64Bignumulonginteger/string

sfixed32总是4个字节int32intintint32Fixnum 或者 Bignum(根据须要)intinteger

sfixed64总是8个字节int64longint/longint64Bignumlonginteger/string

bool boolbooleanboolboolTrueClass/FalseClassboolboolean

string一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。
stringStringstr/unicodestringString (UTF-8)stringstring

bytes可能包含任意顺序的字节数据。
stringByteStringstr[]byteString (ASCII-8BIT)ByteStringstring

.proto TypeNotesC++ TypeJava TypePython Type[2]Go TypeRuby TypeC# TypePHP Type

你可以在文章Protocol Buffer 编码中,找到更多“序列化时各种类型如何编码”的信息。

在java中,无符号32位和64位整型被表示成他们的整型对应形似,最高位被储存在标志位中。
对付所有的情形,设定值会实行类型检讨以确保此值是有效。
64位或者无符号32位整型在解码时被表示成为ilong,但是在设置时可以利用int型值设定,在所有的情形下,值必须符合其设置其类型的哀求。
python中string被表示成在解码时表示成unicode。
但是一个ASCIIstring可以被表示成str类型。
Integer在64位的机器上利用,string在32位机器上利用默认值

当一个被解析的时候,如果被编码的信息不包含一个特定的singular元素,被解析的工具所对应的域被设置为一个默认值,对付不同类型指定如下:

对付strings,默认是一个空string对付bytes,默认是一个空的bytes对付bools,默认是false对付数值类型,默认是0对付列举,默认是第一个定义的列举值,必须为0;对付类型(message),域没有被设置,确切的是根据措辞确定的,详见generated code guide对付可重复域的默认值是空(常日情形下是对应措辞中空列表)。
注:对付标量域,一旦被解析,就无法判断域开释被设置为默认值(例如,例如boolean值是否被设置为false)还是根本没有被设置。
你该当在定义你的类型时非常把稳。
例如,比如你不应该定义boolean的默认值false作为任何行为的触发办法。
也该当把稳如果一个标量域被设置为标志位,这个值不应该被序列化传输。
查看generated code guide选择你的措辞的默认值的事情细节。
列举

当须要定义一个类型的时候,可能想为一个字段指定某“预定义值序列”中的一个值。
例如,假设要为每一个SearchRequest添加一个 corpus字段,而corpus的值可能是UNIVERSAL,WEB,IMAGES,LOCAL,NEWS,PRODUCTS或VIDEO中的一个。
实在可以很随意马虎地实现这一点:通过向定义中添加一个列举(enum)并且为每个可能的值定义一个常量就可以了。

不才面的例子中,在格式中添加了一个叫做Corpus的列举类型——它含有所有可能的值 ——以及一个类型为Corpus的字段:

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;}

如你所见,Corpus列举的第一个常量映射为0:每个列举类型必须将其第一个类型映射为0,这是由于:

必须有有一个0值,我们可以用这个0值作为默认值。
这个零值必须为第一个元素,为了兼容proto2语义,列举类的第一个值总是默认值。
你可以通过将不同的列举常量指定位相同的值。
如果这样做你须要将allow_alias设定为true,否则编译器会在别名的地方产生一个缺点信息。
1234567891011enum EnumAllowingAlias { option allow_alias = true; UNKNOWN = 0; STARTED = 1; RUNNING = 1;}enum EnumNotAllowingAlias { UNKNOWN = 0; STARTED = 1; // RUNNING = 1; // Uncommenting this line will cause a compile error inside Google and a warning message outside.}列举常量必须在32位整型值的范围内。
由于enum值是利用可变编码办法的,对负数不足高效,因此不推举在enum中利用负数。
如上例所示,可以在 一个定义的内部或外部定义列举——这些列举可以在.proto文件中的任何定义里重用。
当然也可以在一个中声明一个列举类型,而在另一个不同 的中利用它——采取MessageType.EnumType的语法格式。
当对一个利用了列举的.proto文件运行protocol buffer编译器的时候,天生的代码中将有一个对应的enum(对Java或C++来说),或者一个分外的EnumDescriptor类(对 Python来说),它被用来在运行时天生的类中创建一系列的整型值符号常量(symbolic constants)。
在反序列化的过程中,无法识别的列举值会被保存在中,虽然这种表示办法须要依据所利用措辞而定。
在那些支持开放列举类型超出指定例模之外的措辞中(例如C++和Go),未识别的值会被表示成所支持的整型。
在利用封闭列举类型的措辞中(Java),利用列举中的一个类型来表示未识别的值,并且可以利用所支持整型来访问。
在其他情形下,如果解析的被序列号,未识别的值将保持原样。
关于如何在你的运用程序的中利用列举的更多信息,请查看所选择的措辞generated code guide利用其他类型你可以将其他类型用作字段类型。
例如,假设在每一个SearchResponse中包含Result,此时可以在相同的.proto文件中定义一个Result类型,然后在SearchResponse中指定一个Result类型的字段,如:123456789message SearchResponse { repeated Result results = 1;} message Result { string url = 1; string title = 2; repeated string snippets = 3;}嵌套类型你可以在其他类型中定义、利用类型,不才面的例子中,Result就定义在SearchResponse内,如:12345678message SearchResponse { message Result { string url = 1; string title = 2; repeated string snippets = 3; } repeated Result results = 1;}如果你想在它的父类型的外部重用这个类型,你须要以Parent.Type的形式利用它,如:

message SomeOtherMessage {SearchResponse.Result result = 1;}

更新一个类型

如果一个已有的格式已无法知足新的需求——如,要在中添加一个额外的字段——但是同时旧版本写的代码仍旧可用。
不用担心!
更新而不毁坏已有代码是非常大略的。
在更新时只要记住以下的规则即可。

不要变动任何已有的字段的数值标识。
如果你增加新的字段,利用旧格式的字段仍旧可以被你新产生的代码所解析。
你该当记住这些元素的默认值这样你的新代码就可以以适当的办法和旧代码产生的数据交互。
相似的,通过新代码产生的也可以被旧代码解析:只不过新的字段会被忽略掉。
把稳,未被识别的字段会在反序列化的过程中丢弃掉,以是如果再被通报给新的代码,新的字段依然是不可用的(这和proto2中的行为是不同的,在proto2中未定义的域依然会随着被序列化)非required的字段可以移除——只要它们的标识号在新的类型中不再利用(更好的做法可能是重命名那个字段,例如在字段前添加“OBSOLETE_”前缀,那样的话,利用的.proto文件的用户将来就不会无意中重新利用了那些不该利用的标识号)。
int32, uint32, int64, uint64,和bool是全部兼容的,这意味着可以将这些类型中的一个转换为其余一个,而不会毁坏向前、 向后的兼容性。
如果解析出来的数字与对应的类型不符合,那么结果就像在C++中对它进行了逼迫类型转换一样(例如,如果把一个64位数字当作int32来 读取,那么它就会被截断为32位的数字)。
sint32和sint64是相互兼容的,但是它们与其他整数类型不兼容。
string和bytes是兼容的——只要bytes是有效的UTF-8编码。
嵌套与bytes是兼容的——只要bytes包含该的一个编码过的版本。
fixed32与sfixed32是兼容的,fixed64与sfixed64是兼容的。
列举类型与int32,uint32,int64和uint64相兼容(把稳如果值不相兼容则会被截断),然而在客户端反序列化之后他们可能会有不同的处理办法,例如,未识别的proto3列举类型会被保留在中,但是他的表示办法会依照措辞而定。
int类型的字段总会保留他们的Any

Any类型许可你在没有指定他们的.proto定义的情形下利用作为一个嵌套类型。
一个Any类型包括一个可以被序列化bytes类型的任意,以及一个URL作为一个全局标识符和解析类型。
为了利用Any类型,你须要导入import google/protobuf/any.proto

import "google/protobuf/any.proto";message ErrorStatus {string message = 1;repeated google.protobuf.Any details = 2;}

对付给定的类型的默认类型URL是type.googleapis.com/packagename.messagename。

不同措辞的实现会支持动态库以线程安全的办法去帮助封装或者解封装Any值。
例如在java中,Any类型会有分外的pack()和unpack()访问器,在C++中会有PackFrom()和UnpackTo()方法。

// 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 ...}}

目前,用于Any类型的动态库仍在开拓之中 如果你已经很熟习proto2语法,利用Any更换拓展

Oneof

如果你的中有很多可选字段, 并且同时至多一个字段会被设置, 你可以加强这个行为,利用oneof特性节省内存.

Oneof字段就像可选字段, 除了它们会共享内存, 至多一个字段会被设置。
设置个中一个字段会打消其它字段。
你可以利用case()或者WhichOneof() 方法检讨哪个oneof字段被设置, 看你利用什么措辞了.

利用Oneof

为了在.proto定义Oneof字段, 你须要在名字前面加上oneof关键字, 比如下面例子的test_oneof:

message SampleMessage {oneof test_oneof {string name = 4;SubMessage sub_message = 9;}}

然后你可以增加oneof字段到 oneof 定义中. 你可以增加任意类型的字段, 但是不能利用repeated 关键字.

在产生的代码中, oneof字段拥有同样的 getters 和setters, 就像正常的可选字段一样. 也有一个分外的方法来检讨到底那个字段被设置. 你可以在相应的措辞API指南中找到oneof API先容.

Oneof 特性设置oneof会自动打消其它oneof字段的值. 以是设置多次后,只有末了一次设置的字段有值.

SampleMessage message;message.set_name("name");CHECK(message.has_name());message.mutable_sub_message(); // Will clear name field.CHECK(!message.has_name());如果解析器碰着同一个oneof中有多个成员,只有末了一个会被解析成。
oneof不支持repeated.反射API对oneof 字段有效.如果利用C++,需确保代码不会导致内存泄露. 下面的代码会崩溃, 由于sub_message 已经通过set_name()删除了

SampleMessage message;SubMessage sub_message = message.mutable_sub_message();message.set_name("name"); // Will delete sub_messagesub_message->set_... // Crashes here在C++中,如果你利用Swap()两个oneof,每个,两个将拥有对方的值,例如不才面的例子中,msg1会拥有sub_message并且msg2会有name。

SampleMessage msg1;msg1.set_name("name");SampleMessage msg2;msg2.mutable_sub_message();msg1.swap(&msg2);CHECK(msg1.has_sub_message());CHECK(msg2.has_name());向后兼容性问题

当增加或者删除oneof字段时一定要小心. 如果检讨oneof的值返回None/NOT_SET, 它意味着oneof字段没有被赋值或者在一个不同的版本中赋值了。
你不会知道是哪种情形,由于没有办法判断如果未识别的字段是一个oneof字段。

Tage 重用问题:

将字段移入或移除oneof:在被序列号或者解析后,你大概会失落去一些信息(有些字段大概会被打消)删除一个字段或者加入一个字段:在被序列号或者解析后,这大概会打消你现在设置的oneof字段分离或者领悟oneof:行为与移动常规字段相似。
Map(映射)

如果你希望创建一个关联映射,protocol buffer供应了一种快捷的语法:

map<key_type, value_type> map_field = N;

个中key_type可以是任意Integer或者string类型(以是,除了floating和bytes的任意标量类型都是可以的)value_type可以是任意类型。

例如,如果你希望创建一个project的映射,每个Projecct利用一个string作为key,你可以像下面这样定义:

map<string, Project> projects = 3;Map的字段可以是repeated。
序列化后的顺序和map迭代器的顺序是不愿定的,以是你不要期望以固定顺序处理Map当为.proto文件产生天生文本格式的时候,map会按照key 的顺序排序,数值化的key会按照数值排序。
从序列化中解析或者领悟时,如果有重复的key则后一个key不会被利用,当从文本格式中解析map时,如果存在重复的key。

天生map的API现在对付所有proto3支持的措辞都可用了,你可以从API指南找到更多信息。

向后兼容性问题

map语法序列化后等同于如下内容,因此纵然是不支持map语法的protocol buffer实现也是可以处理你的数据的:

message MapFieldEntry { key_type key = 1; value_type value = 2;}repeated MapFieldEntry map_field = N;

当然可以为.proto文件新增一个可选的package声明符,用来防止不同的类型有命名冲突。
如:

package foo.bar;message Open { ... }

  在其他的格式定义中可以利用包名+名的办法来定义域的类型,如:

message Foo {required foo.bar.Open open = 1;}

包的声明符会根据利用措辞的不同影响天生的代码。

对付C++,产生的类会被包装在C++的命名空间中,如上例中的Open会被封装在 foo::bar空间中; - 对付Java,包声明符会变为java的一个包,除非在.proto文件中供应了一个明确有java_package;对付 Python,这个包声明符是被忽略的,由于Python模块是按照其在文件系统中的位置进行组织的。
对付Go,包可以被用做Go包名称,除非你显式的供应一个option go_package在你的.proto文件中。
对付Ruby,天生的类可以被包装在内置的Ruby名称空间中,转换成Ruby所需的大小写样式 (首字母大写;如果第一个符号不是一个字母,则利用PB_前缀),例如Open会在Foo::Bar名称空间中。
对付javaNano包会利用Java包,除非你在你的文件中显式的供应一个option java_package。
对付C#包可以转换为PascalCase后作为名称空间,除非你在你的文件中显式的供应一个option csharp_namespace,例如,Open会在Foo.Bar名称空间中包及名称的解析

Protocol buffer措辞中类型名称的解析与C++是同等的:首先从最内部开始查找,依次向外进行,每个包会被看作是其父类包的内部类。
当然对付 (foo.bar.Baz)这样以“.”分隔地意味着是从最外围开始的。

ProtocolBuffer编译器会解析.proto文件中定义的所有类型名。
对付不同措辞的代码天生器会知道如何来指向每个详细的类型,纵然它们利用了不同的规则。

定义做事(Service)

如果想要将类型用在RPC(远程方法调用)系统中,可以在.proto文件中定义一个RPC做事接口,protocol buffer编译器将会根据所选择的不同措辞天生做事接口代码及存根。
如,想要定义一个RPC做事并具有一个方法,该方法能够吸收 SearchRequest并返回一个SearchResponse,此时可以在.proto文件中进行如下定义:

service SearchService {rpc Search (SearchRequest) returns (SearchResponse);}

最直不雅观的利用protocol buffer的RPC系统是gRPC一个由谷歌开拓的措辞和平台中的开源的PRC系统,gRPC在利用protocl buffer时非常有效,如果利用分外的protocol buffer插件可以直接为您从.proto文件中产生干系的RPC代码。

如果你不想利用gRPC,也可以利用protocol buffer用于自己的RPC实现,你可以从proto2措辞指南中找到更多信息

还有一些第三方开拓的PRC实现利用Protocol Buffer。
参考第三方插件wiki查看这些实现的列表。

JSON 映射

Proto3 支持JSON的编码规范,使它更随意马虎在不同系统之间共享数据,不才表中逐个描述类型。

如果JSON编码的数据丢失或者其本身便是null,这个数据会在解析成protocol buffer的时候被表示成默认值。
如果一个字段在protocol buffer中表示为默认值,体会在转化成JSON的时候编码的时候忽略掉以节省空间。
详细实现可以供应在JSON编码中可选的默认值。

messageobject{“fBar”: v, “g”: null, …}产生JSON工具,字段名可以被映射成lowerCamelCase形式,并且成为JSON工具键,null被接管并成为对应字段的默认值

enumstring“FOO_BAR”列举值的名字在proto文件中被指定

mapobject{“k”: v, …}所有的键都被转换成string

repeated Varray[v, …]null被视为空列表

booltrue, falsetrue, false

stringstring“Hello World!”

bytesbase64 string“YWJjMTIzIT8kKiYoKSctPUB+”

int32, fixed32, uint32number1, -10, 0JSON值会是一个十进制数,数值型或者string类型都会接管

int64, fixed64, uint64string“1”, “-10”JSON值会是一个十进制数,数值型或者string类型都会接管

float, doublenumber1.1, -10.0, 0, “NaN”, “Infinity”JSON值会是一个数字或者一个指定的字符串如”NaN”,”infinity”或者”-Infinity”,数值型或者字符串都是可接管的,指数符号也可以接管

Anyobject{“@type”: “url”, “f”: v, … }如果一个Any保留一个特上述的JSON映射,则它会转换成一个如下形式:{"@type": xxx, "value": yyy}否则,该值会被转换成一个JSON工具,@type字段会被插入所指定的确定的值

Timestampstring“1972-01-01T10:00:20.021Z”利用RFC 339,个中天生的输出将始终是Z-归一化啊的,并且利用0,3,6或者9位小数

Durationstring“1.000340012s”, “1s”天生的输出总是0,3,6或者9位小数,详细依赖于所须要的精度,接管所有可以转换为纳秒级的精度

Structobject{ … }任意的JSON工具,见struct.proto

Wrapper typesvarious types2, “2”, “foo”, true, “true”, null, 0, …包装器在JSON中的表示办法类似于基本类型,但是许可nulll,并且在转换的过程中保留null

FieldMaskstring“f.fooBar,h”见fieldmask.proto

ListValuearray[foo, bar, …]

Valuevalue 任意JSON值

NullValuenull JSON null

proto3JSONJSON示例把稳

选项

在定义.proto文件时能够标注一系列的options。
Options并不改变全体文件声明的含义,但却能够影响特定环境下处理办法。
完全的可用选项可以在google/protobuf/descriptor.proto找到。

一些选项是文件级别的,意味着它可以浸染于最外范围,不包含在任何内部、enum或做事定义中。
一些选项是级别的,意味着它可以用在定义的内部。
当然有些选项可以浸染在域、enum类型、enum值、做事类型及做事方法中。
到目前为止,并没有一种有效的选项能浸染于所有的类型。

如下便是一些常用的选择:

java_package (文件选项) :这个选项表明天生java类所在的包。
如果在.proto文件中没有明确的声明java_package,就采取默认的包名。
当然了,默认办法产生的 java包名并不是最好的办法,按照运用名称倒序办法进行排序的。
如果不须要产生java代码,则该选项将不起任何浸染。
如:

option java_package = "com.example.foo";java_outer_classname (文件选项): 该选项表明想要天生Java类的名称。
如果在.proto文件中没有明确的java_outer_classname定义,天生的class名称将会根据.proto文件的名称采取驼峰式的命名办法进行天生。
如(foo_bar.proto天生的java类名为FooBar.java),如果不天生java代码,则该选项不起任何浸染。
如:

option java_outer_classname = "Ponycopter";

optimize_for(文件选项): 可以被设置为 SPEED, CODE_SIZE,或者LITE_RUNTIME。
这些值将通过如下的办法影响C++及java代码的天生:

SPEED (default): protocol buffer编译器将通过在类型上实行序列化、语法剖析及其他通用的操作。
这种代码是最优的。
CODE_SIZE: protocol buffer编译器将会产生最少量的类,通过共享或基于反射的代码来实现序列化、语法剖析及各种其它操作。
采取该办法产生的代码将比SPEED要少得多, 但是操作要相对慢些。
当然实现的类及其对外的API与SPEED模式都是一样的。
这种办法常常用在一些包含大量的.proto文件而且并不盲目追求速率的 运用中。
LITE_RUNTIME: protocol buffer编译器依赖于运行时核心类库来天生代码(即采取libprotobuf-lite 替代libprotobuf)。
这种核心类库由于忽略了一 所描述符及反射,要比全类库小得多。
这种模式常常在移动手机平台运用多一些。
编译器采取该模式产生的方法实现与SPEED模式不相上下,产生的类通过实现 MessageLite接口,但它仅仅是Messager接口的一个子集。
option optimize_for = CODE_SIZE;cc_enable_arenas(文件选项):对付C++产生的代码启用arena allocationobjc_class_prefix(文件选项):设置Objective-C类的前缀,添加到所有Objective-C从此.proto文件产生的类和列举类型。
没有默认值,所利用的前缀该当是苹果推举的3-5个大写字符,把稳2个字节的前缀是苹果所保留的。
deprecated(字段选项):如果设置为true则表示该字段已经被废弃,并且不应该在新的代码中利用。
在大多数措辞中没有实际的意义。
在java中,这回变成@Deprecated注释,在未来,其他措辞的代码天生器大概会在字标识符中产生废弃注释,废弃注释会在编译器考试测验利用该字段时发出警告。
如果字段没有被利用你也不肯望有新用户利用它,考试测验利用保留语句更换字段声明。

int32 old_field = 6 [deprecated=true];自定义选项

ProtocolBuffers许可自定义并利用选项。
该功能该当属于一个高等特性,对付大部分人是用不到的。
如果你的确希望创建自己的选项,请参看 Proto2 Language Guide。
把稳创建自定义选项利用了拓展,拓展只在proto3中可用。

原文链接: https://www.cnblogs.com/tohxyblog/p/8974763.html

标签:

相关文章

介绍皮肤设置,如何打造理想肌肤状态

随着科技的发展和人们对美的追求,皮肤设置已成为美容护肤的重要一环。如何根据皮肤类型、肤质、年龄等因素进行合理设置,已成为众多爱美人...

网站建设 2025-01-03 阅读1 评论0

介绍盖章制作,传承文化,彰显权威

自古以来,盖章在我国文化中具有重要的地位。从古代的官印、私印到现代的公章、合同章,盖章已成为一种独特的文化符号,承载着丰富的历史内...

网站建设 2025-01-03 阅读1 评论0

介绍监控破坏,技术手段与法律风险并存

随着科技的飞速发展,监控设备已遍布大街小巷,成为维护社会治安的重要手段。一些不法分子为了逃避法律制裁,开始研究如何破坏监控设备。本...

网站建设 2025-01-03 阅读1 评论0

介绍登录不上之谜,技术故障还是人为疏忽

随着互联网的普及,登录已成为人们日常生活中不可或缺的一部分。在享受便捷的登录不上这一问题也困扰着许多用户。本文将深入剖析登录不上之...

网站建设 2025-01-03 阅读1 评论0

介绍电脑键盘调出方法,让操作更高效

随着科技的发展,电脑已经成为了我们日常生活中不可或缺的工具。而电脑键盘,作为电脑输入设备,更是我们与电脑进行交流的桥梁。你是否知道...

网站建设 2025-01-03 阅读1 评论0

介绍磁力链,高效便捷的文件下载利器

在互联网高速发展的今天,文件下载已成为日常生活中不可或缺的一部分。而磁力链作为一种新型的文件下载方式,凭借其高效、便捷的特点,受到...

网站建设 2025-01-03 阅读1 评论0