[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-detail-ssr-46028460304370700":3},{"id":4,"title":5,"tag":6,"createTime":7,"updateTime":7,"renderedHtml":8,"description":9,"ogImageUrl":10},"46028460304370700","Protocol Buffer v3 语法","微服务","2023-11-14","\u003Ch2 id=\"h2-0-\">简单入门\u003C\u002Fh2>\n\u003Cp>Protobuf 是一种语言无关、平台无关、可扩展的序列化结构数据的协议（类似于 XML、JSON、YAML 等），可以用于通信协议、数据存储等领域。通过 protobuf 工具生成的代码文件，为开发者提供了在目标语言（如 Go、Java、Python 等）中使用 protobuf 定义的数据结构的便利，同时也自动实现了相应的序列化和反序列化操作。\u003C\u002Fp>\n\u003Cp>先来新建一个 user.proto 文件，这个 user.proto 文件的作用就是定义各种消息体，然后通过 protoc 编译器来生成相应的语言能使用的文件。\u003C\u002Fp>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"text\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">text\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">3\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">4\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">5\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">6\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">7\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">8\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">9\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">10\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-text\">\u003Cspan class=\"ssr-code-line\">syntax = &quot;proto3&quot;;\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">option go_package = &quot;.\u002Fservice;userRPC&quot;;\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">package user;\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">message User{\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">  string username = 1;\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">  int32 age = 2;\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">}\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Cp>这个文件有一些需要说明的地方：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\n\u003Cp>syntax = “proto3”;表示使用的协议为 proto3，proto3 和 proto2 这两个版本的语法有一点区别，所以需要指定这个文件使用的是那个版本的协议（语法）对数据进行序列化和反序列化\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>go_package 是一个 protobuf 选项。格式为：\u003Ccode>go_package=&quot;path;name&quot;\u003C\u002Fcode>。在说详细一点：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>path：path 表示生成的 go 文件的存放地址。这个路径如果是一个相对路径，那就是相对于当前的.proto 文件的相对路径。\u003C\u002Fli>\n\u003Cli>name：name 表示生成的\u003Ccode>go文件\u003C\u002Fcode>所属的包名。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>package user;表示定义了消息类型的命名空间。这样就可以解决在不同的.proto 文件中定义的消息类型产生命名冲突。例如，你可能在两个不同的.proto 文件中都定义了一个名为 User 的消息类型，那么使用 package 可以避免这种冲突。也就是可以使用 user.User 来引用定义在 user 包中的 User 消息。\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>message 用于定义一个消息体，消息体也可以支持嵌套定义（message 里面有 message）。\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>定义好消息后，就可以生成相应语言（如 Go、Java、Python 等）的对应文件。在这里使用 protoc --go_out=. user.proto 命令生成相应的 go 文件。protoc 表示使用 protoc 编辑器；–go_out 是一个编译选项；最后是需要编译的.proto 文件。编译完成之后就会得到一个 user.pb.go 文件，文件名当中的 pb 是 ProtocolBuffers 的缩写。\u003C\u002Fp>\n\u003Cp>这个 user.pb.go 文件的作用就是定义 User 类型的结构体以及与之相关的序列化和反序列化的代码。这样，你的 Go 程序就可以创建 User 实例，设置它的字段，将它序列化为字节流，或是从字节流中反序列化出 User 实例。\u003C\u002Fp>\n\u003Ch3 id=\"h3-1--demo\">写一个 demo\u003C\u002Fh3>\n\u003Cp>使用 protoc --go_out=. user.proto 命令生成 user.pb.go 文件后就可以使用 go 语言完成 user 消息的序列化和反序列化的操作了。\u003C\u002Fp>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"text\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">text\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">3\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">4\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">5\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">6\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">7\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">8\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">9\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">10\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">11\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">12\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">13\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">14\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-text\">\u003Cspan class=\"ssr-code-line\">func main() {\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\tuser := userRPC.User{\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\t\tUserName: &quot;bing&quot;,\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\t\tAge:      20,\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\t}\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\t\u002F\u002F序列化\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\tmarshal, _ := proto.Marshal(&amp;user)\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\tfmt.Println(marshal)\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\t\u002F\u002F反序列化\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\tvar newUser = new(userRPC.User)\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\t_ = proto.Unmarshal(marshal, newUser)\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\tfmt.Println(newUser)\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">}\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Cp>运行结果如下：\u003C\u002Fp>\n\u003Cp>\u003Cimg class=\"article-img article-img-zoomable\" src=\"https:\u002F\u002Fliubing-1314895948.cos.ap-chengdu.myqcloud.com\u002Fimg\u002F202311041719769.png\" alt=\"image-20231104171941674\" loading=\"lazy\" decoding=\"async\" style=\"width: 100%; height: auto; max-width: 100%; display: block;\" srcset=\"https:\u002F\u002Fliubing-1314895948.cos.ap-chengdu.myqcloud.com\u002Fimg\u002F202311041719769.png?imageMogr2\u002Fthumbnail\u002F400x\u002Fformat\u002Fwebp\u002Fquality\u002F85 400w, https:\u002F\u002Fliubing-1314895948.cos.ap-chengdu.myqcloud.com\u002Fimg\u002F202311041719769.png?imageMogr2\u002Fthumbnail\u002F800x\u002Fformat\u002Fwebp\u002Fquality\u002F85 800w, https:\u002F\u002Fliubing-1314895948.cos.ap-chengdu.myqcloud.com\u002Fimg\u002F202311041719769.png?imageMogr2\u002Fthumbnail\u002F1200x\u002Fformat\u002Fwebp\u002Fquality\u002F85 1200w, https:\u002F\u002Fliubing-1314895948.cos.ap-chengdu.myqcloud.com\u002Fimg\u002F202311041719769.png?imageMogr2\u002Fthumbnail\u002F1920x\u002Fformat\u002Fwebp\u002Fquality\u002F85 1920w\" sizes=\"(max-width: 576px) 100vw, (max-width: 992px) 90vw, 720px\">\u003C\u002Fp>\n\u003Ch2 id=\"h2-2-protocol-buffers-\">protocol buffers 语法详解\u003C\u002Fh2>\n\u003Ch3 id=\"h3-3-\">字段规则\u003C\u002Fh3>\n\u003Cp>在 Protocol Buffers v3 中，字段规则定义了字段的数量，即字段在消息中可以出现的次数。每个字段必须有一个字段规则，字段规则可以是以下之一：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>optional\u003C\u002Fcode>：字段可以在消息中出现 0 次或 1 次。尽管 Protocol Buffers v3 中的所有字段都是可选的，但是在 .proto 文件中不需要明确地写出 optional 关键字，因为这是默认的字段规则。\u003C\u002Fli>\n\u003Cli>\u003Ccode>repeated\u003C\u002Fcode>：字段可以在消息中出现任意次数，包括 0 次。如果一个字段被设置为 repeated，那么这个字段的值将被表示为一个数组。\u003C\u002Fli>\n\u003Cli>\u003Ccode>required\u003C\u002Fcode>：字段必须在消息中出现 1 次。这个字段规则在 Protocol Buffers v3 中被移除了，因为这会使消息的更新变得困难。在 Protocol Buffers v3 中，所有字段都是可选的。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>例如，以下是一个使用了 optional 和 repeated 字段规则的消息定义：\u003C\u002Fp>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"protobuf\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">protobuf\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">3\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">4\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">5\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">6\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-protobuf\">\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">syntax\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;proto3&quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">message\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Student\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">string\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> name \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">repeated\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">int32\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> scores \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">2\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Cp>在这个例子中，name 字段是可选的，可以在消息中出现 0 次或 1 次，scores 字段是重复的，可以在消息中出现任意次数。\u003C\u002Fp>\n\u003Ch3 id=\"h3-4-\">数据类型\u003C\u002Fh3>\n\u003Cp>Protocol Buffers 中的字段类型可以分为以下几类：\u003C\u002Fp>\n\u003Col>\n\u003Cli>标量类型：包括整型、浮点型、布尔型、字符串型、字节型等。\u003C\u002Fli>\n\u003Cli>枚举类型：定义一组命名的值。\u003C\u002Fli>\n\u003Cli>消息类型：可以定义复杂的数据类型。\u003C\u002Fli>\n\u003Cli>重复字段类型：可以包含一组同类型的元素。\u003C\u002Fli>\n\u003Cli>映射字段类型：可以包含一组键值对。\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>以下是一个 user.proto 文件的示例，其中包含了所有这些类型：\u003C\u002Fp>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"text\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">text\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">3\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">4\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">5\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">6\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">7\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">8\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">9\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">10\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">11\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">12\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">13\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">14\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-text\">\u003Cspan class=\"ssr-code-line\">\u002F\u002F 枚举类型\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">enum UserRole {\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">  USER = 0;\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">  ADMIN = 1;\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">}\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u002F\u002F 消息类型\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">message UserInfo {\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">  string username = 1;  \u002F\u002F 标量类型\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">  int32 age = 2;  \u002F\u002F 标量类型\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">  UserRole role = 3;  \u002F\u002F 枚举类型\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">  repeated string email = 4;  \u002F\u002F 重复字段类型\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">  map&lt;string, string&gt; attributes = 5;  \u002F\u002F 映射字段类型\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">}\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Ch3 id=\"h3-5-\">标量值类型\u003C\u002Fh3>\n\u003Cp>标量消息字段可以具有以下类型之一。该表显示了.proto 文件，以及自动生成类中的对应类型:\u003C\u002Fp>\n\u003Cdiv class=\"ssr-table-wrap\">\u003Cbutton class=\"ssr-table-fs-btn\" type=\"button\" aria-label=\"全屏查看表格\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cdiv class=\"ssr-table-scroll\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth style=\"text-align:left\">.proto Type\u003C\u002Fth>\n\u003Cth style=\"text-align:left\">Notes\u003C\u002Fth>\n\u003Cth style=\"text-align:left\">C++ Type\u003C\u002Fth>\n\u003Cth style=\"text-align:left\">Java\u002FKotlin Type\u003Csup>[1]\u003C\u002Fsup>\u003C\u002Fth>\n\u003Cth style=\"text-align:left\">Python Type\u003Csup>[3]\u003C\u002Fsup>\u003C\u002Fth>\n\u003Cth style=\"text-align:left\">Go Type\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd style=\"text-align:left\">double\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">double\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">double\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">float\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">float64\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd style=\"text-align:left\">float\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">float\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">float\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">float\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">float32\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd style=\"text-align:left\">int32\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">使用可变长度编码。编码负数效率低下——如果你的字段可能有负值，则使用 sint32代替。\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int32\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int32\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd style=\"text-align:left\">int64\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">使用可变长度编码。编码负数效率低下——如果你的字段可能有负值，则使用 sint64代替。\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int64\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">long\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int\u002Flong\u003Csup>[4]\u003C\u002Fsup>\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int64\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd style=\"text-align:left\">uint32\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">使用变长编码。\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">uint32\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int\u003Csup>[2]\u003C\u002Fsup>\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int\u002Flong\u003Csup>[4]\u003C\u002Fsup>\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">uint32\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd style=\"text-align:left\">uint64\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">使用变长编码。\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">uint64\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int\u003Csup>[2]\u003C\u002Fsup>\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int\u002Flong\u003Csup>[4]\u003C\u002Fsup>\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">uint64\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd style=\"text-align:left\">sint32\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">使用可变长度编码。带符号的 int 值。这些编码比普通的 int32更有效地编码负数。\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int32\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int32\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd style=\"text-align:left\">sint64\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">使用可变长度编码。带符号的 int 值。这些编码比普通的 int64更有效地编码负数。\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int64\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">long\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int\u002Flong\u003Csup>[4]\u003C\u002Fsup>\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int64\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd style=\"text-align:left\">fixed32\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">总是四个字节。如果值经常大于228，则比 uint32更有效率。\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">uint32\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int\u003Csup>[2]\u003C\u002Fsup>\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int\u002Flong\u003Csup>[4]\u003C\u002Fsup>\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">uint32\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd style=\"text-align:left\">fixed64\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">总是8字节。如果值经常大于256，则比 uint64更有效率。\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">uint64\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">integer\u002Fstring\u003Csup>[6]\u003C\u002Fsup>\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd style=\"text-align:left\">sfixed32\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">总是四个字节。\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int32\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int32\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd style=\"text-align:left\">sfixed64\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">总是八个字节。\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">int64\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">integer\u002Fstring\u003Csup>[6]\u003C\u002Fsup>\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd style=\"text-align:left\">bool\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">bool\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">boolean\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">bool\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">bool\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd style=\"text-align:left\">string\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">字符串必须始终包含 UTF-8编码的或7位 ASCII 文本，且不能长于232。\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">string\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">String\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">str\u002Funicode\u003Csup>[5]\u003C\u002Fsup>\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">string\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd style=\"text-align:left\">bytes\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">可以包含任何不超过232字节的任意字节序列。\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">string\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">ByteString\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">str (Python 2) bytes (Python 3)\u003C\u002Ftd>\n\u003Ctd style=\"text-align:left\">[]byte\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cp>[1] Kotlin 使用来自 Java 的相应类型，甚至是无符号类型，以确保在混合 Java\u002FKotlin 代码库中的兼容性。\n[2] 在 Java 中，无符号的 32 位和 64 位整数使用它们的有符号整数表示，顶部的位简单地存储在符号位中。\n[3] 在所有情况下，将值设置为字段将执行类型检查，以确保它是有效的。\n[4]64 位或无符号 32 位整数在解码时总是表示为 long，但如果在设置字段时给出了 int，则可以表示为 int。在所有情况下，值必须符合设置时表示的类型。参见[2]。\n[5]Python 字符串在解码时表示为 unicode，但如果给出 ASCII 字符串则可以表示为 str(这可能会更改)。\n[6] 整数在 64 位机器上使用，字符串在 32 位机器上使用\u003C\u002Fp>\n\u003Ch3 id=\"h3-6-\">默认值\u003C\u002Fh3>\n\u003Cp>在 Protocol Buffers v3 中，每种数据类型都有一个默认值。如果在消息中没有设置字段的值，那么这个字段的值将被设置为其数据类型的默认值。\u003C\u002Fp>\n\u003Cul>\n\u003Cli>对于字符串，默认值为空字符串。\u003C\u002Fli>\n\u003Cli>对于字节，默认值为空字节。\u003C\u002Fli>\n\u003Cli>对于 bool，默认值为 false。\u003C\u002Fli>\n\u003Cli>对于数字类型，默认值为零。\u003C\u002Fli>\n\u003Cli>对于枚举，默认值是第一个定义的 enum 值，必须为 0。\u003C\u002Fli>\n\u003Cli>对于消息字段，没有设置该字段。它的确切值取决于语言。\u003C\u002Fli>\n\u003Cli>重复字段的默认值是空数组。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Ccode>注意\u003C\u002Fcode>：\u003C\u002Fp>\n\u003Col>\n\u003Cli>\n\u003Cp>在 Protocol Buffers v3 中，如果字段的值是默认值，那么这个字段将不会被序列化，也就是说它不会出现在序列化后的字节流中。这是一种称为 “zero value omission” 的优化，可以帮助节省网络带宽和存储空间。\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>例如，如果你有一个 message，它的一个字段是 int32 类型的，值为 0（这是 int32 类型的默认值），那么在序列化这个 message 时，这个字段不会被包含在序列化后的字节流中。当反序列化这个字节流时，由于这个字段没有在字节流中，所以它的值将被设置为默认值，也就是 0。这对于可选字段和单一字段来说是非常有用的。\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>但是对于 repeated 字段和 map 字段来说，如果它们的值是空数组或者空映射，它们仍然会被序列化，因为这是有意义的信息：它告诉我们这个字段被设置了，只是它的值为空。\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch3 id=\"h3-7-unknown-fields\">Unknown Fields\u003C\u002Fh3>\n\u003Cp>未知字段是指在解析一个消息时，消息中存在字段编号，但是在对应的消息定义中并没有找到这个字段编号对应的字段。这种情况通常发生在消息的定义已经发生了变化，但是正在解析的消息是旧版本的消息。\u003C\u002Fp>\n\u003Cp>在 Protocol Buffers v3 中，未知字段会被忽略，也就是说它们不会被包含在解析后的消息中。但是它们会被存储在一个特殊的数据结构中，所以如果你再次将这个消息序列化，这些未知字段还会被包含在序列化后的字节流中。\u003C\u002Fp>\n\u003Cp>为了便于理解，以下是一个示例：\u003C\u002Fp>\n\u003Col>\n\u003Cli>首先，我们定义一个消息：\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"protobuf\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">protobuf\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">3\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">4\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">5\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">6\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-protobuf\">\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">syntax\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;proto3&quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">message\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">ExampleMessage\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">int32\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> id \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">string\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> name \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">2\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Col start=\"2\">\n\u003Cli>然后，我们创建一个这样的消息，并将它序列化：\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"go\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">go\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-go\">\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">msg \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">ExampleMessage\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">{id: \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">123\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, name: \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;Alice&quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">data, _ \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> proto.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Marshal\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(msg)\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Col start=\"3\">\n\u003Cli>之后，我们改变 ExampleMessage 的定义，移除了 name 字段：\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"protobuf\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">protobuf\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">3\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">4\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">5\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-protobuf\">\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">syntax\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;proto3&quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">message\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">ExampleMessage\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">int32\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> id \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Col start=\"4\">\n\u003Cli>然后我们尝试将之前序列化的字节流反序列化为新的 ExampleMessage：\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"go\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">go\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-go\">\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">newMsg \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">ExampleMessage\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">{}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">_ \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> proto.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Unmarshal\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(data, newMsg)\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Cp>在这个例子中，name 字段在 ExampleMessage 的新定义中不存在，所以它是一个未知字段。当我们解析字节流时，name 字段的值会被忽略，不会被包含在 newMsg 中。\u003Ccode>但是如果我们再次将 newMsg 序列化，name 字段还会被包含在序列化后的字节流中。\u003C\u002Fcode>\u003C\u002Fp>\n\u003Ch3 id=\"h3-8-\">保留字段\u003C\u002Fh3>\n\u003Cp>在 Protocol Buffer 中，有时可能需要改变一个消息类型的定义，比如删除一个字段或者修改字段的类型。这些改动可能会使得新的定义和旧的定义不兼容，导致解析出错。为了避免这种情况，Protocol Buffer 提供了保留字段（Reserved Fields）的特性。\u003C\u002Fp>\n\u003Cp>如果你在一个消息类型中保留了一个字段，那么在这个消息类型的任何后续定义中都不能再使用这个字段的编号或者名称。\u003C\u002Fp>\n\u003Cp>为了便于理解，以下是一个示例：\u003C\u002Fp>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"protobuf\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">protobuf\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">3\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">4\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">5\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">6\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">7\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">8\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-protobuf\">\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">message\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">ExampleMessage\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">reserved\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">2\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">3\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">reserved\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;foo&quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;bar&quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">int32\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> id \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D\">\u002F\u002F 已删除或注释的字段：\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D\">\u002F\u002F int32 foo = 2;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D\">\u002F\u002F string bar = 3;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Cp>在这个例子中，我们在 ExampleMessage 中保留了编号为 2 和 3 的字段，\u003Ccode>以及\u003C\u002Fcode>名称为 “foo” 和 “bar” 的字段。这意味着在 ExampleMessage 的任何后续定义中，我们都不能再使用这些字段编号和字段名称。\u003C\u002Fp>\n\u003Cp>如果我们尝试使用被保留的\u003Ccode>字段编号\u003C\u002Fcode>或\u003Ccode>字段名称\u003C\u002Fcode>，编译器就会报错。例如，下面的定义就会导致编译错误：\u003C\u002Fp>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"protobuf\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">protobuf\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">3\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">4\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-protobuf\">\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">message\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">ExampleMessage\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">int32\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> qux \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">2\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;  \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D\">\u002F\u002F 错误：字段编号 2 已经被保留\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">string\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> bar \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">4\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;  \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D\">\u002F\u002F 错误：字段名称 &quot;bar&quot; 已经被保留\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Ch3 id=\"h3-9-\">更新消息类型\u003C\u002Fh3>\n\u003Cp>在 Protocol Buffers 中，更新消息类型通常涉及添加新的字段或删除不再需要的字段。当你更改了消息类型的定义后，新的和旧的代码必须能够相互兼容，以确保系统的平稳运行。以下是一些注意事项：\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>添加新字段\u003C\u002Fstrong>：当你添加新字段时，你应该为它分配一个新的、尚未使用的字段编号。旧代码读取包含新字段的消息时，会将新字段视为未知并忽略它。新代码读取不包含新字段的消息时，将为新字段使用默认值。\u003C\u002Fli>\n\u003Cli>\u003Cstrong>删除字段\u003C\u002Fstrong>：当你不再需要某个字段时，你应该删除该字段的代码，并在消息中用 reserved 保留该字段的编号和名称。这样可以防止未来不小心重新使用这个编号或名称。\u003C\u002Fli>\n\u003Cli>\u003Cstrong>不要更改字段的编号和数据类型\u003C\u002Fstrong>：如果你更改了字段的编号或数据类型，新的和旧的代码就可能无法正确解析彼此的消息。这可能导致数据丢失或其他错误。\u003C\u002Fli>\n\u003Cli>\u003Cstrong>枚举\u003C\u002Fstrong>：如果你需要更新枚举类型，你可以添加新的枚举值，但不应删除现有的枚举值，也不应更改枚举值的名称或编号。这是因为旧的代码可能仍然在使用被删除或更改的枚举值。\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>总的来说，更新 Protocol Buffers 的消息类型需要小心，并遵循一些规则，以确保新的和旧的代码能够相互兼容。\u003C\u002Fp>\n\u003Ch3 id=\"h3-10-any\">Any\u003C\u002Fh3>\n\u003Cp>\u003Ccode>Any\u003C\u002Fcode> 是 Protocol Buffers 中的一个特殊类型，它可以存储任何类型的消息。Any 包含两部分信息：一个是消息的全名（包括包名和消息名），一个是消息的字节串。Any 类型的主要用途是让你可以将任何消息作为字段存储在另一个消息中，而不需要事先知道这个消息的具体类型。\u003C\u002Fp>\n\u003Cp>为了便于理解，以下是一个示例：\u003C\u002Fp>\n\u003Col>\n\u003Cli>首先，定义消息：\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"protobuf\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">protobuf\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">3\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">4\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">5\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">6\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">7\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">8\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">9\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-protobuf\">\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">import\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;google\u002Fprotobuf\u002Fany.proto&quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">message\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">MessageA\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">int32\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> a \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">message\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Wrapper\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">google.protobuf.Any\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> any \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Col start=\"2\">\n\u003Cli>然后，我们可以将 MessageA 的实例存储在 wrapper 中，再将 wrapper 进行序列化：\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"go\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">go\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">3\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">4\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">5\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-go\">\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">msgA \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">MessageA\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">{a: \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">123\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">anyA, _ \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> anypb.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">New\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(msgA)\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">wrapper \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Wrapper\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">{\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">any\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">: anyA}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">data, _ \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> proto.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Marshal\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(wrapper)\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Col start=\"3\">\n\u003Cli>之后，我们可以从 wrapper 中取出 Any 类型的字段，并将它转换回原来的类型：\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"go\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">go\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">3\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">4\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">5\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">6\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">7\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">8\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">9\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-go\">\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">newWrapper \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Wrapper\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">{}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">_ \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> proto.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Unmarshal\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(data, newWrapper)\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">newMsgA \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">MessageA\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">{}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">if\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> err \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> anypb.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">UnmarshalTo\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(newWrapper.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">any\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, newMsgA, \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">proto\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">UnmarshalOptions\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">{}); err \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">==\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">nil\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  fmt.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Printf\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;MessageA: \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">%v\\n\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, newMsgA)\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">} \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">else\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  fmt.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Printf\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;Error: \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">%v\\n\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, err)\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Cp>在这个例子当中，我们使用 google.protobuf.Any 作为 Wrapper 的一部分，这让我们可以将任何类型的消息存储在 Wrapper 中。最后打印的结果为：MessageA: a:123\u003C\u002Fp>\n\u003Ch3 id=\"h3-11-oneof\">oneof\u003C\u002Fh3>\n\u003Cp>在 Protocol Buffers v3 中，\u003Ccode>oneof\u003C\u002Fcode> 是一种特殊的字段类型，表示在一组字段中只能有一个设置值，或者说其中的字段是互斥的。这可以用于表示&quot;或&quot;关系，比如一个对象可以是 A 类型或者 B 类型，但不能同时是两种。\u003C\u002Fp>\n\u003Cp>为了方便理解，举个例子：\u003C\u002Fp>\n\u003Col>\n\u003Cli>先定义一个 Student 类型，这个类型包含一个 oneof 字段，可以是 home_address（家庭地址）或 dorm_address（宿舍地址）。\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"protobuf\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">protobuf\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">3\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">4\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">5\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">6\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">7\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">8\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">9\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">10\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">11\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-protobuf\">\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">syntax\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;proto3&quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">message\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Student\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">    \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">string\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> name \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">    \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">int32\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> age \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">2\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">    \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">oneof\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> address {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">        \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">string\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> home_address \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">3\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">        \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">string\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> dorm_address \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">4\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">    }\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Col start=\"2\">\n\u003Cli>然后使用 protoc 编译器将文件进行编译后，就可以使用 go 语言来使用 Student 类型。\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"go\" data-collapsible=\"true\" data-collapsed=\"true\" data-line-count=\"38\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">go\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-toggle ssr-code-toggle--head ssr-code-iconbtn\" type=\"button\" aria-expanded=\"true\" aria-label=\"收起代码\" title=\"收起\">\u003Csvg viewBox=\"0 0 24 24\" width=\"19\" height=\"19\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M12 8.59l-6.3 6.3 1.4 1.42L12 11.4l4.9 4.9 1.4-1.4z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-toggle ssr-code-toggle--head-expand ssr-code-iconbtn\" type=\"button\" aria-expanded=\"false\" aria-label=\"展开代码\" title=\"展开\">\u003Csvg viewBox=\"0 0 24 24\" width=\"19\" height=\"19\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M12 15.41l6.3-6.3-1.4-1.42L12 12.59 7.1 7.7l-1.4 1.4z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">3\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">4\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">5\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">6\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">7\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">8\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">9\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">10\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">11\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">12\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">13\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">14\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">15\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">16\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">17\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">18\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">19\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">20\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">21\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">22\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">23\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">24\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">25\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">26\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">27\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">28\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">29\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">30\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">31\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">32\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">33\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">34\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">35\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">36\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">37\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">38\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-go\">\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">func\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">main\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">() {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\u003C\u002Fspan>\u003Cspan style=\"color:#6A737D\">\u002F\u002F 创建一个 Student 实例\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\tstudent \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">demo\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Student\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">{\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\tName: \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;张三&quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\tAge:  \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">20\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\tAddress: \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">demo\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Student_HomeAddress\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">{\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\t\tHomeAddress: \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;翻斗大街翻斗花园2号楼1001室&quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\t},\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\u003C\u002Fspan>\u003Cspan style=\"color:#6A737D\">\u002F\u002F 序列化 Student 对象\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\tdata, err \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> proto.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Marshal\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(student)\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">if\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> err \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">!=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">nil\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\tlog.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Fatal\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;Marshaling error: &quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, err)\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\u003C\u002Fspan>\u003Cspan style=\"color:#6A737D\">\u002F\u002F 创建一个新的 Student 对象\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\tnewStudent \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">demo\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Student\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">{}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\u003C\u002Fspan>\u003Cspan style=\"color:#6A737D\">\u002F\u002F 反序列化数据到新的 Student 对象\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\terr \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> proto.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Unmarshal\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(data, newStudent)\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">if\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> err \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">!=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">nil\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\tlog.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Fatal\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;Unmarshal error: &quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, err)\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\u003C\u002Fspan>\u003Cspan style=\"color:#6A737D\">\u002F\u002F 打印新的 Student 对象\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\tfmt.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Println\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(newStudent)\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\u003C\u002Fspan>\u003Cspan style=\"color:#6A737D\">\u002F\u002F 单独打印地址信息\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">switch\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> addr \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> newStudent.Address.(\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">type\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">case\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">*\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">demo\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Student_HomeAddress\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">:\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\tfmt.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Println\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;Home address:&quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, addr.HomeAddress)\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">case\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">*\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">demo\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Student_DormAddress\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">:\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\tfmt.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Println\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;Dorm address:&quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, addr.DormAddress)\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">default\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">:\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\tfmt.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Println\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;No address&quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-mask\" aria-hidden=\"true\">\u003C\u002Fdiv>\u003Cbutton class=\"ssr-code-toggle ssr-code-toggle--floating\" type=\"button\" aria-expanded=\"false\">展开全部 (38 行)\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Cp>在这个例子中，我们首先创建了一个 Student 对象，然后将这个对象序列化为字节流，再将这个字节流反序列化为一个新的 Student 对象。最后，我们使用类型断言和 switch 语句来检查 oneof 字段的类型，并打印相应的地址。\u003C\u002Fp>\n\u003Cp>运行结果如下：\u003C\u002Fp>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"text\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">text\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-text\">\u003Cspan class=\"ssr-code-line\">name:&quot;张三&quot;  age:20  home_address:&quot;翻斗大街翻斗花园2号楼1001室&quot;\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">Home address: 翻斗大街翻斗花园2号楼1001室\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Ch3 id=\"h3-12-json-\">JSON 映射\u003C\u002Fh3>\n\u003Cp>在 Protocol Buffers v3 中，JSON 映射是指将 Protocol Buffers 消息类型与 JSON 对象之间的转换规则。这种映射允许开发者方便地在 Protocol Buffers 和 JSON 之间进行数据转换。\u003C\u002Fp>\n\u003Cp>为了便于理解，举个例子：\u003C\u002Fp>\n\u003Col>\n\u003Cli>首先，定义一个 Protobuf 消息类型 Student：\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"protobuf\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">protobuf\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">3\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">4\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-protobuf\">\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">message\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Student\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">string\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> name \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">int32\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> age \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">2\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Col start=\"2\">\n\u003Cli>然后，就可以使用 protojson 包来将 Protobuf 消息转换为 JSON，或者将 JSON 转换为 Protobuf 消息：\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"go\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">go\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">3\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">4\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">5\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">6\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">7\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">8\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">9\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">10\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">11\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">12\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">13\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">14\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">15\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">16\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">17\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">18\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-go\">\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">func\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">main\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">() {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\tstudent \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">demo\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Student\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">{Name: \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;张三&quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, Age: \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">20\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\u003C\u002Fspan>\u003Cspan style=\"color:#6A737D\">\u002F\u002F 将 Student 消息转换为 JSON\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\tjsonData, err \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> protojson.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Marshal\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(student)\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">if\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> err \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">!=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">nil\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\tlog.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Fatal\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(err)\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\tfmt.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Println\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">string\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(jsonData))\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\u003C\u002Fspan>\u003Cspan style=\"color:#6A737D\">\u002F\u002F 将 JSON 转换为 Student 消息\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\tjsonData \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> []\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">byte\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">`{&quot;name&quot;:&quot;李四&quot;,&quot;age&quot;:21}`\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\tnewStudent \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">&amp;\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">demo\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Student\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">{}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">if\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> err \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">:=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> protojson.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Unmarshal\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(jsonData, newStudent); err \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">!=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">nil\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t\tlog.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Fatal\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(err)\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\t}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">\tfmt.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">Printf\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;Name: \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">%s\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">, Age: \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">%d\\n\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">&quot;\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, newStudent.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">GetName\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(), newStudent.\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">GetAge\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">())\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Cp>运行结果如下：\u003C\u002Fp>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"text\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">text\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-text\">\u003Cspan class=\"ssr-code-line\">{&quot;name&quot;:&quot;张三&quot;,&quot;age&quot;:20}\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">Name: 李四, Age: 21\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Ch3 id=\"h3-13-\">定义服务\u003C\u002Fh3>\n\u003Cp>在 Protocol Buffers v3 中，你可以使用 \u003Ccode>service\u003C\u002Fcode> 关键字来定义一个服务。服务由一组 RPC（远程过程调用）方法组成，每个方法都有一个指定的请求类型和响应类型。\u003C\u002Fp>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"protobuf\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">protobuf\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">3\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">4\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">5\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">6\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">7\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">8\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">9\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">10\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">11\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">12\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">13\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">14\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">15\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">16\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">17\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-protobuf\">\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">message\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">StudentRequest\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">string\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> id \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">message\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">GetStudentResponse\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">string\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> name \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">int32\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> age \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">2\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">message\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">CreateStudentResponse\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">bool\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> success \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">​\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#F97583\">service\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">StudentService\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">rpc\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">GetStudent\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">StudentRequest\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">) \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">returns\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">GetStudentResponse\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">) {}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">  \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">rpc\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">CreateStudent\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">StudentRequest\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">) \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">returns\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\">CreateStudentResponse\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">) {}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Ch2 id=\"h2-14--grpc-\">编译 gRPC 服务\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\n\u003Cp>在 Go 的 Protocol Buffers API v2 版本及以后，原来的插件（\u003Ccode>protoc-gen-go\u003C\u002Fcode>）将不再提供对 gRPC 服务的生成。\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>在 Protocol Buffers API v2 中，通过新的模块 \u003Ccode>google.golang.org\u002Fprotobuf\u003C\u002Fcode>（protobuf 的 Go 实现）提供了许多增强的功能和改进，与旧模块 \u003Ccode>github.com\u002Fgolang\u002Fprotobuf\u003C\u002Fcode> 相区分。这个新模块能更好地与 Go 语言的特性和生态系统集成。\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>所以，生成 protobuf 和 gRPC 代码的推荐做法就是分别使用 \u003Ccode>protoc-gen-go\u003C\u002Fcode> 和 \u003Ccode>protoc-gen-go-grpc\u003C\u002Fcode>这两个插件。\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>安装插件：\u003C\u002Fp>\n\u003Cdiv class=\"ssr-code-block\" data-lang=\"bash\">\u003Cdiv class=\"ssr-code-head\">\u003Cspan class=\"ssr-code-lang\">bash\u003C\u002Fspan>\u003Cdiv class=\"ssr-code-actions\">\u003Cbutton class=\"ssr-code-fullscreen ssr-code-iconbtn\" type=\"button\" aria-label=\"全屏查看代码\" title=\"全屏\">\u003Csvg viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M5 5h6v2H7v4H5V5zm14 0v6h-2V7h-4V5h6zM5 19v-6h2v4h4v2H5zm14 0h-6v-2h4v-4h2v6z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003Cbutton class=\"ssr-code-copy ssr-code-iconbtn\" type=\"button\" aria-label=\"复制代码\" title=\"复制\">\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--default\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--success\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\u002F>\u003C\u002Fsvg>\u003Csvg class=\"ssr-code-copy-icon ssr-code-copy-icon--error\" viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" aria-hidden=\"true\">\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\u002F>\u003C\u002Fsvg>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"ssr-code-body\">\u003Cdiv class=\"ssr-code-pane\">\u003Cdiv class=\"ssr-code-gutter\" aria-hidden=\"true\">\u003Cspan class=\"ssr-code-num\">1\u003C\u002Fspan>\u003Cspan class=\"ssr-code-num\">2\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cpre class=\"ssr-code-pre\">\u003Ccode class=\"hljs language-bash\">\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#B392F0\">go\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">install\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">google.golang.org\u002Fprotobuf\u002Fcmd\u002Fprotoc-gen-go@latest\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"ssr-code-line\">\u003Cspan style=\"color:#B392F0\">go\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">install\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">google.golang.org\u002Fgrpc\u002Fcmd\u002Fprotoc-gen-go-grpc@latest\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>\n\u003Cp>这样，protoc 命令也发生了变化，从旧的单一插件命令变为了现在两个独立插件的形式：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>protoc --go_out=. demo.proto\u003C\u002Fcode> 用于生成 protobuf 消息结构的代码。\u003C\u002Fli>\n\u003Cli>\u003Ccode>protoc --go-grpc_out=. demo.proto\u003C\u002Fcode> 用于生成 gRPC 服务的代码。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>但是这两个命令还是可以合并为一个命令：\u003Ccode>protoc --go_out=. --go-grpc_out=. demo.proto\u003C\u002Fcode>\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Ful>\n","简单入门 Protobuf 是一种语言无关、平台无关、可扩展的序列化结构数据的协议（类似于 XML、JSON、YAML 等），可以用于通信协议、数据存储等领域。通过 protobuf 工具生成的代码文件，为开发者提供了在目标语言（如 Go、Java、Python 等）中使用 protobuf 定义的数据结构的便利，同时","https:\u002F\u002Fliubing-1314895948.cos.ap-chengdu.myqcloud.com\u002Fimg\u002F202311041719769.png"]