当前位置: 首页 > news >正文

上海住房城乡建设厅网站烟台建设局网站

上海住房城乡建设厅网站,烟台建设局网站,wordpress aplayer,衡阳网站排名优化目录protobuf介绍protobuf使用protoc命令语法定义消息类型指定字段类型分配字段编号指定字段规则添加更多消息类型注释保留字段从.proto文件生成了什么#xff1f;值类型默认值枚举使用其他消息类型导入定义嵌套类型更新消息类型未知字段any任意类型oneofoneof 特性兼容性问题… 目录protobuf介绍protobuf使用protoc命令语法定义消息类型指定字段类型分配字段编号指定字段规则添加更多消息类型注释保留字段从.proto文件生成了什么值类型默认值枚举使用其他消息类型导入定义嵌套类型更新消息类型未知字段any任意类型oneofoneof 特性兼容性问题MapsPackages定义服务JSON 映射Options参考文档protobuf介绍 Protobuf是Protocol Buffer的简称它是Google公司于2008年开源的一种高效的平台无关、语言无关、可扩展的数据格式目前Protobuf作为接口规范的描述语言可以作为Go语言RPC接口的基础工具。 protobuf使用 protobuf是一个与语言无关的一个数据协议所以我们需要先编写IDL文件然后借助专用工具生成指定语言的代码从而实现数据的序列化与反序列化过程。 大致开发流程如下 1. IDL编写 2. 生成指定语言的代码 3. 序列化和反序列化 protoc命令 protoc --proto_pathIMPORT_PATH --cpp_outDST_DIR --java_outDST_DIR --python_outDST_DIR --go_outDST_DIR --ruby_outDST_DIR --objc_outDST_DIR --csharp_outDST_DIR path/to/file.protoIMPORT_PATH指定寻找proto 的目录去解决import 带来的依赖问题如果省略默认是当前文件夹。多个import 文件夹可以通过参数使用–proto_path多次来解决编译器将会按顺序搜索。也可以用简写-IIMPORT_PATH来表示–proto_path–cpp_out–java_out–go_out等等代表指定生成的语言可以生成多个语言path/to/file.proto 代表输入的proto 文件可以用*.proto 代表输入文件夹内多个文件 语法 定义消息类型 syntax proto3;message SearchRequest {string query 1;int32 page_number 2;int32 result_per_page 3; }文件第一行指定您使用的语法如果不这样做编译器将假定使用的是proto2。这必须是.proto3文件的第一个非空、非注释行。消息定义指定了三个字段名称/值对每个字段对应于要包含在该类型消息中的数据段。 指定字段类型 在上面的示例中所有字段都是标量类型scalar types: 两个整数(page_number和 result_per_page)和一个字符串(query)。但是也可以为字段指定组合类型包括枚举和其他消息类型。 分配字段编号 消息定义中的每个字段都有一个唯一编号。这些字段编号用于标识消息二进制格式的字段并且在消息类型投入使用后不应更改。请注意1到15范围内的字段编号需要一个字节进行编码编码内包括字段号和字段类型参考协议缓冲区编码。16到2047范围内的字段编号需要两个字节(进行编码)。因此您应该把1到15的消息编号留给非常频繁出现的消息元素。请记住为将来可能添加的频繁出现的元素留出一些空间。可以指定的最小字段号为1最大字段号为(2**29)-1字段数字会作为keykey最后三位是类型或536870911。您也不能使用数字19000到19999(字段描述符)因为它们是协议缓冲区的保留数字如果你在你的.proto中使用了这些数字编译器会报错。同样不能使用任何以前保留的字段号。 指定字段规则 消息字段可以是下列字段之一: singular: 格式正确的消息可以有这个字段的零个或一个(但不能多于一个)。这是 proto3语法的默认字段规则。repeated: 该字段可以在格式正确的消息中重复任意次数(包括零次)。重复值的顺序将被保留。 在 proto3中标量数值类型的repeated字段默认使用packed编码。(参考Protocol Buffer Encoding可以找到关于packed编码的更多信息 添加更多消息类型 可以在一个.proto 文件中定义多个消息类型。如果想定义与 SearchRequest 消息类型对应的应答消息格式SearchResponse就可以将其添加到同一个.proto文件中。 message SearchRequest {string query 1;int32 page_number 2;int32 result_per_page 3; }message SearchResponse {... }注释 .proto文件使用了C/C风格的//和/* ... */语法。 /* SearchRequest 表示一个分页查询 * 其中有一些字段指示响应中包含哪些结果 */message SearchRequest {string query 1;int32 page_number 2; // 页码数int32 result_per_page 3; // 每页返回的结果数 }保留字段 如果通过完全删除某个字段或把它注释掉来更新消息类型则将来的用户可以在对该类型进行自己的更新时重用该字段编号。如果以后加载相同.proto的旧版本这可能会导致数据损坏、隐私漏洞等严重问题。确保不会发生这种情况的一种方法是使用reserved关键字指定已删除字段的字段编号为保留编号也要指定已删除字段名称为保留名称(name)以规避JSON序列化问题。将来有任何用户试图使用这些字段标识符时协议缓冲区编译器将报错。 message Foo {reserved 2, 15, 9 to 11;reserved foo, bar; }注意不能在同一个reserved语句中混合字段名和字段编号。 从.proto文件生成了什么 当使用 protocol buffer 编译器来运行.proto文件时编译器用选择的语言生成描述的消息类型包括获取和设置字段值将消息序列化为输出流以及从输入流解析消息的代码。 对于PythonPython 编译器为.proto文件中的每个消息类型生成一个带静态描述符的模块然后与 metaclass 一起使用在运行时创建必要的 Python 数据访问类。 对于 Go编译器为文件中的每种消息类型生成一个类型type到一个.pb.go 文件。 其他… 值类型 .proto TypeNotesC TypeJava/Kotlin Type[1]Python Type[3]Go TypePHP Typedoubledoubledoublefloatfloat64floatfloatfloatfloatfloatfloat32floatint32使用可变长度编码。编码负数效率低下——如果你的字段可能有负值则使用 sint32代替。int32intintint32integerint64使用可变长度编码。编码负数效率低下——如果你的字段可能有负值则使用 sint64代替。int64longint/long[4]int64integer/string[6]uint32使用变长编码。uint32int[2]int/long[4]uint32integeruint64使用变长编码。uint64long[2]int/long[4]uint64integer/string[6]sint32使用可变长度编码。带符号的 int 值。这些编码比普通的 int32更有效地编码负数。int32intintint32integersint64使用可变长度编码。带符号的 int 值。这些编码比普通的 int64更有效地编码负数。int64longint/long[4]int64integer/string[6]fixed32总是四个字节。如果值经常大于228则比 uint32更有效率。uint32int[2]int/long[4]uint32integerfixed64总是8字节。如果值经常大于256则比 uint64更有效率。uint64integer/string[6]sfixed32总是四个字节。int32intintint32integersfixed64总是八个字节。int64integer/string[6]boolboolbooleanboolboolbooleanstring字符串必须始终包含 UTF-8编码的或7位 ASCII 文本且不能长于232。stringStringstr/unicode[5]stringstringbytes可以包含任何不超过232字节的任意字节序列。stringByteStringstr (Python 2) bytes (Python 3)[]bytestring 默认值 当解析消息时如果编码消息不包含特定的 singular 元素则解析对象中的相应字段将设置为该字段的默认值。 string默认值为空字符串bytes默认值为空字节boolean默认值为false数值类型默认值为0枚举默认值为第一个定义的枚举值该值必须是0消息字段不设默认值它的确切值取决于语言。repeated 字段的默认值为空(通常是适配语言中的空列表)。 枚举 定义消息类型时可能希望其中一个字段只包含预定义值列表中的一个 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 enum 的第一个常量映射为零每个 enum 定义必须包含一个常量该常量映射为零且作为它的第一个元素。这是因为: 必须有一个零值这样我们就可以使用0作为数值默认值。零值必须是第一个元素以便与 proto2语义兼容其中第一个枚举值总是默认值。 可以通过将相同的值赋给不同的枚举常量来定义别名。为此需要将allow_alias选项设置为true否则协议编译器将在找到别名时将生成错误消息。 message MyMessage1 {enum EnumAllowingAlias {// 允许别名option allow_alias true;UNKNOWN 0;STARTED 1;RUNNING 1;} } message MyMessage2 {enum EnumNotAllowingAlias {UNKNOWN 0;STARTED 1;// RUNNING 1; // 取消对此行的注释将导致内部出现编译错误外部出现警告消息。} }枚举器常量必须在32位整数的范围内。由于enum使用可变编码因此负值效率很低所以不建议使用。您可以在定义的消息内部定义枚举如上面的示例所示也可以在外部定义枚举——这些枚举可以在.proto文件中的任何消息定义中重用。您还可以使用_MessageType_._EnumType_语法将一条消息中声明的枚举类型用作另一条消息中的字段类型。当使用协议缓冲区编译器编译一个使用了枚举的.proto文件时对于Python会生成一个特殊EnumDescriptor类用于在运行时生成的类中创建一组具有整数值的符号常量。 syntax proto3; option go_package protos/pbs; enum TestType {Hello10;Hello21;Hello32;Hello43; }message HelloRequest {string greeting 1;TestType en2; }message HelloResponse {string reply 1; }使用其他消息类型 当使用其他消息的时候如果在本文件直接使用就可以了。Result代表自定义消息类型 message SearchResponse {repeated Result results 1; }message Result {string url 1;string title 2;// []stringrepeated string snippets 3; }导入定义 可以通过 import 来使用来自其他 .proto 文件的定义。 import myproject/other_protos.proto;默认情况下只能从直接导入的 .proto 文件中使用定义。但是有时你可能需要将 .proto 文件移动到新的位置这样就可以在旧目录放一个占位的.proto文件使用import public 将所有导入转发到新位置而不必直接移动.proto文件并修改所有的地方。 任何导入包含import public语句的proto的人都可以传递地依赖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.protoprotocol 编译器使用命令行-I/–proto_path参数指定的一组目录中搜索导入的文件。如果没有给该命令行参数则查看调用编译器的目录。 一般来说应该将 --proto_path 参数设置为项目的根目录并为所有导入使用正确的名称。 // user_business.proto syntax proto3; option go_package protos/pbs; import share/user.proto; //获取角色信息请求 message GetUserRequest {} //获取角色信息响应 message GetUserResponse {User user1; }// user.proto syntax proto3; option go_package protos/pbs;//用户定义 message User {string Id1;string Name2;string Age3; }嵌套类型 可以在其他消息类型中定义和使用消息类型在 SearchResponse消息中定义Result: message 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; }可以随心所欲地将信息一层又一层嵌入其中: message Outer { // Level 0message MiddleAA { // Level 1message Inner { // Level 2int64 ival 1;bool booly 2;}}message MiddleBB { // Level 1message Inner { // Level 2int32 ival 1;bool booly 2;}} }更新消息类型 如果现有的消息类型不再满足你的所有需要例如消息格式需要增加一个字段但是仍然希望使用用旧格式创建的代码。在不破坏任何现有代码的情况下更新消息类型非常简单只需遵守以下规则 不要更改任何现有字段的字段编号如果添加新字段则使用“旧”消息格式的代码序列化的任何消息仍然可以由新生成的代码进行解析。你应该记住这些元素的默认值以便新代码可以正确地与旧代码生成的消息交互。类似地由新代码创建的消息也可以由旧代码解析旧二进制文件在解析时忽略新字段。可以删除字段前提是在更新的消息类型中不再使用此字段编号。您可能需要重命名字段或者添加前缀OBSOLETE_或者使用reserved保留字段编号以便.proto的未来用户不会意外地重用该编号。int32、 uint32、 int64、 uint64和 bool都是兼容的——这意味着你可以在不破坏向前或向后兼容性的情况下将一个字段从这些类型中的一个更改为另一个。如果一个数字被解析到一个并不适当的类型中你会得到与在 C 中将数字转换为该类型相同的效果(例如如果一个64位的数字被读作 int32它将被截断为32位)sint32和 sint64相互兼容但与其他整数类型不兼容。string和bytes是兼容的只要字节是有效的 UTF-8。如果bytes包含消息的编码版本则嵌入的消息与字节兼容。fixed32与 sfixed32兼容 fixed64与 sfixed64兼容。对于string、bytes和消息字段optional字段与repeated字段兼容。给定重复字段的序列化数据作为输入如果该字段是基元类型字段则期望该字段为optional(可选的)字段的客户端将获取最后一个输入值如果该字段是消息类型字段则合并所有输入元素。请注意对于数值类型包括bool和enum这通常是不安全的。数字类型的重复字段可以按压缩格式序列化当需要可选字段时将无法正确解析压缩格式。enum 在格式方面与 int32、 uint32、int64和 uint64兼容(请注意如果不适合值将被截断)。但是要注意当消息被反序列化时客户端代码可能会对它们进行不同的处理例如未识别的proto3枚举类型将保留在消息中但在反序列化消息时如何表示这些类型取决于客户端语言。整型字段总是保持它们的值。将单个值更改为新的oneof成员是安全的并且二进制兼容。如果确保没有代码一次设置多个字段那么将多个字段移动到新的oneof字段中可能是安全的。将任何字段移到现有oneof字段中都不安全。 未知字段 未知字段是格式良好的协议缓冲区序列化数据表示解析器无法识别的字段。例如当一个旧二进制代码解析一个带有新字段的新二进制代码发送的数据时这些新字段在旧二进制代码中成为未知字段。最初proto3消息在解析过程中总是丢弃未知字段但在3.5版中重新引入了未知字段的保留以匹配proto2的行为。在版本3.5和更高版本中解析期间保留未知字段并将其包含在序列化输出中。 any任意类型 Any 消息类型允许你将消息作为嵌入类型使用而不需要其 .proto 定义。Any包含一个以字节表示的任意序列化消息以及一个URL该URL充当该消息的全局唯一标识符并解析为该消息的类型。要使用 Any类型需要导入google/protobuf/any.proto。如果编译报错将上述文件下载好复制到自己的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()方法。 oneof 如果在平时在一个消息有许多字段但是最多设置一个字段我们可以使用oneof 来执行并节省内存。 Oneof 字段类似于常规字段除了Oneof共享内存的所有字段之外最多可以同时设置一个字段。设置Oneof 的任何成员都会自动清除所有其他成员。您可以使用case()或WhichOneof()方法检查Oneof 中的哪个值被设置(如果有的话)具体取决于选择的语言。 syntax proto3; option go_package protos/pbs;message SubMessage {int32 Id1;string Age22;} message SampleMessage {oneof test_oneof {string name 4;SubMessage sub_message 9;} }要定义 oneof 字段需要在你的.proto文件中使用oneof关键字并在后面跟上名称然后将其中一个字段添加到该字段的定义中。你可以添加任何类型的字段除了map字段和repeated字段。 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 不支持repeated。反射作用于oneof的字段。 package mainimport (fmtgrpcdemo/protobuf/any/protos/pbs )func main() {p:pbs.SampleMessage{TestOneof: pbs.SampleMessage_Name{Name: hello},}fmt.Println(p)fmt.Println(p.GetTestOneof())p.TestOneofpbs.SampleMessage_SubMessage{SubMessage: pbs.SubMessage{Id: 1}}fmt.Println(p)fmt.Println(p.GetTestOneof()) }兼容性问题 添加或删除其中一个字段时要小心。如果检查 oneof 的值返回 None/NOT_SET则可能意味着 oneof 尚未设置或已设置为 oneof 的另一个字段。这种情况是无法区分的因为无法知道未知字段是否是 oneof 成员。 标签重用问题 将 optional 可选字段移入或移出 oneof在序列化和解析 message 后你可能会丢失一些信息某些字段将被清除。但是你可以安全地将单个字段移动到新的 oneof 中并且如果已知只有一个字段被设置则可以移动多个字段。删除 oneof 字段并将其重新添加回去在序列化和解析 message 后这可能会清除当前设置的 oneof 字段。拆分或合并 oneof这与移动常规的 optional 字段有类似的问题。 Maps mapkey_type, value_type map_field N;message Project {key_type key 1;value_type value 2; }// 比如key是string val是Project类型 mapstring, Project projects 3;其中key_type可以是任何整型或字符串类型(因此除了浮点类型和字节之外的任何标量类型)。注意enum不是一个有效的key_type。value_type可以是除其他map以外的任何类型。 映射字段不能使用repeated关键字。映射值的Wire格式排序和映射迭代排序未定义因此不能依赖特定顺序的映射项。 为.proto生成文本格式时映射按键排序。数字键按数字排序。如果为映射字段提供键但没有值则序列化字段时的行为与语言有关。在C、Java和Python中类型的默认值被序列化而在其他语言中没有任何序列化。生成的map API目前适用于所有proto3支持的语言。 Packages 可以向.proto文件中添加可选的package明符以防止协议消息类型之间的名称冲突 可以理解为go的包。 package foo.bar; message Open { ... }定义服务 如果要在RPCRemote Procedure Call远程过程调用系统中使用消息类型可以在.proto文件中定义RPC服务接口。 service SearchService {rpc Search(SearchRequest) returns (SearchResponse); }JSON 映射 proto3JSONJSON example描述【译】messageobject{fooBar: v, g: null, …}生成JSON对象。消息字段名被映射到lowerCamelCase并成为JSON对象键。如果指定了json_name选项则指定的值将用作键。解析器接受小驼峰命秘法名称或由json_name选项指定的名称和原始proto字段名称。null是所有字段类型的可接受值并被视为相应字段类型的默认值。enumstringFOO_BAR使用proto中指定的枚举值的名称。解析器接受枚举名和整数值。mapK,Vobject{k: v, …}所有键都转换为字符串。repeated Varray[v, …]null被接受为空列表[]。booltrue, falsetrue, falsestringstringHello World!bytesbase64 stringYWJjMTIzIT8kKiYoKSctPUBJSON值将是使用带填充的标准base64编码的字符串编码的数据。包含或不包含填充的标准或url安全base64编码都可以接受。int32, fixed32, uint32number1, -10, 0JSON值将是一个十进制数。可接受数字或字符串。int64, fixed64, uint64string1, -10JSON值将是十进制字符串。可接受数字或字符串。float, doublenumber1.1, -10.0, 0, NaN, InfinityJSON值将是一个数字或特殊字符串值NaN Infinity和-Infinity中的一个。数字或字符串都可以接受。指数符号也被接受。-0被认为等于0。Anyobject{type: url, f: v, … }如果Any类型包含一个具有特殊JSON映射的值它将按如下方式转换{typexxxvalueyyy}。否则该值将转换为JSON对象并插入“type”字段以指示实际的数据类型。Timestampstring1972-01-01T10:00:20.021Z使用RFC3339其中生成的输出将始终是**Z**规格化的并使用0、3、6或9个小数位数。也接受“Z”以外的偏移。Durationstring1.000340012s, 1s生成的输出总是包含0、3、6或9个小数位数(取决于所需的精度)后跟“s”后缀。接受任何小数位数(没有小数也可以)只要它们符合纳秒精度并且需要“s”后缀。Structobject{ … }任何JSON对象。见struct.proto。Wrapper typesvarious types2, 2, foo, true, true, null, 0, …包装器在JSON中使用与包装原语类型相同的表示形式只是在数据转换和传输期间允许并保留null。FieldMaskstringf.fooBar,h见field_mask.protoListValuearray[foo, bar, …]Valuevalue任何JSON值。详见google.protobuf.ValueNullValuenullJSON nullEmptyobject{}空的JSON对象 Options .proto文件中的单个声明可以使用许多 选项 进行注释。选项不会更改声明的总体含义但可能会影响在特定上下文中处理声明的方式。可用选项的完整列表在google/protobuf/descriptor.proto中定义。 deprecated选项 设为true 代表字段被废弃在新代码不应该被使用在大多数语言都没有实际的效果 option go_package tmp/pb; // 指定生成的Go代码在你项目中的导入路径int32 old_field 6 [deprecated true];参考文档 [1] 深入解析protobuf
http://www.tj-hxxt.cn/news/131028.html

相关文章:

  • 太原企业网站建设抖音分享小程序怎么赚钱
  • 公司网站怎样备案广州白云区最新信息
  • wordpress qa专业培训seo的机构
  • 怎么做直播视频教学视频网站wordpress页脚太高
  • 建设手机网站公司社区文化建设
  • 国内百度云网站建设WordPress网站结构优化
  • 下载的网站模板怎么修改ui设计培训一般多久
  • p2p网站制作 杭州班级优化大师学生版
  • 山西建设工程协会网站企业网站推广在哪里办
  • 网站建设平台用乐云践新自己做网站怎么做
  • 兰州网站建设推广报价石家庄建设局网站怎么打不开
  • vr技术对网站建设有哪些影响创意设计与制作
  • 网页游戏网站知乎泉州网站建设选择讯呢
  • go语言 做网站做学校网站的内容
  • 怎么在网站做浮动图标网站建设小程序开发seo推广
  • 涡阳网站建设wordpress字体代码
  • 粉色帝国网站小学网站源码php
  • 网站建设直通车关键词设置163网易企业邮箱
  • 4399谁做的网站工业风 网站建设
  • 做网站哪个语言好山西省建设厅网站首页
  • 云服务器 部署网站wordpress如何配置伪静态页面
  • 2015微信网站设计学校网站建设意见
  • 成都网络优化网站无锡电子商务网站建设公司
  • 唐山网站建设费用西安软件制作公司
  • 中国全球门户网站wordpress标签页模板
  • 做网站是如何赚钱的淘宝网站建设 深圳
  • 珠海网站建设工程桂林象鼻山图片
  • 用手机做网站国外做网站
  • 北京智能网站建设系统加盟北京seo优化诊断
  • 婚恋网站排名前十名wordpress正文页面