• protobuf的复杂结构


    前言

    在写proto文件的时候,想要百度一下都有哪些内容,但是找到的都是那个经典的官方样例,互相之间抄来抄去,所以这里干脆把git上的相关源码,和实际使用经历结合总结下来,给一潭死水里注入一点活力吧。

    常用关键字

    1. syntax:指定proto文件使用的语法版本。
    2. package:指定生成的代码所在的包名。
    3. import:导入其他proto文件。
    4. option:设置特定的选项。
    5. message:定义消息类型。
    6. enum:定义枚举类型。
    7. service:定义服务接口。
    8. rpc:定义远程过程调用方法。
    9. oneof:定义互斥字段,只能选择其中一个字段。
    10. map:定义映射类型,类似于字典。
    11. repeated:定义重复字段,可以有多个值。
    12. required:定义必需字段,必须有值。
    13. optional:定义可选字段,可以有值也可以为空。
    14. extensions:定义扩展字段。
    15. extend:扩展已有的消息类型或枚举类型。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    每个关键字的使用示例

    1. syntax:
    syntax = "proto3";
    
    • 1
    1. package:
    package mypackage;
    
    • 1
    1. import:
    import "google/protobuf/timestamp.proto";
    
    • 1
    1. option:
    option java_package = "com.example.mypackage";
    
    • 1
    1. message:
    message Person {
      string name = 1;
      int32 age = 2;
      repeated string phone_numbers = 3;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. enum:
    enum PhoneType {
      MOBILE = 0;
      HOME = 1;
      WORK = 2;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. service:
    service MyService {
      rpc GetData (GetDataRequest) returns (GetDataResponse);
    }
    
    • 1
    • 2
    • 3
    1. rpc:
    rpc GetData (GetDataRequest) returns (GetDataResponse);
    
    • 1
    1. oneof:
    message Person {
      string name = 1;
      oneof phone_number {
        string mobile = 2;
        string home = 3;
        string work = 4;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. map:
    message Person {
      string name = 1;
      map phone_numbers = 2;
    }
    
    • 1
    • 2
    • 3
    • 4
    1. repeated:
    message Person {
      string name = 1;
      repeated string phone_numbers = 2;
    }
    
    • 1
    • 2
    • 3
    • 4
    1. required:
    message Person {
      required string name = 1;
      required int32 age = 2;
    }
    
    • 1
    • 2
    • 3
    • 4
    1. optional:
    message Person {
      optional string name = 1;
      optional int32 age = 2;
    }
    
    • 1
    • 2
    • 3
    • 4
    1. extensions:
    extend Person {
      extensions 100 to 199;
      optional string email_address = 100;
    }
    
    • 1
    • 2
    • 3
    • 4
    1. extend:
    extend google.protobuf.Timestamp {
      optional string timezone = 1000;
    }
    
    • 1
    • 2
    • 3

    复杂结构

    下面是一些示例,展示了proto文件中的嵌套、数组和以结构体为值的映射的用法:

    1. 嵌套示例:
    syntax = "proto3";
    
    message Address {
      string street = 1;
      string city = 2;
      string state = 3;
    }
    
    message Person {
      string name = 1;
      int32 age = 2;
      Address address = 3;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在上面的示例中,Address是一个嵌套在Person中的消息类型。

    1. 数组示例:
    syntax = "proto3";
    
    message Person {
      string name = 1;
      repeated string phone_numbers = 2;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在上面的示例中,phone_numbers字段是一个字符串数组。

    1. 以结构体为值的映射示例:
    syntax = "proto3";
    
    message Person {
      string name = 1;
      map addresses = 2;
    }
    
    message Address {
      string street = 1;
      string city = 2;
      string state = 3;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在上面的示例中,addresses字段是一个以字符串为键、Address结构体为值的映射。

    1. 自定义枚举值:
    syntax = "proto3";
    
    enum PhoneType {
      MOBILE = 0;
      HOME = 1;
      WORK = 2;
      CUSTOM = 3;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在上面的示例中,我们定义了一个自定义的枚举值CUSTOM。

    1. 扩展字段:
    syntax = "proto3";
    
    message Person {
      string name = 1;
      extensions 100 to 199;
    }
    
    extend Person {
      optional string email = 100;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在上面的示例中,我们使用extend关键字扩展了Person消息类型,添加了一个可选的email字段。

    1. 服务定义和RPC方法:
    syntax = "proto3";
    
    service MyService {
      rpc GetData (GetDataRequest) returns (GetDataResponse);
      rpc UpdateData (UpdateDataRequest) returns (UpdateDataResponse);
    }
    
    message GetDataRequest {
      string id = 1;
    }
    
    message GetDataResponse {
      string data = 1;
    }
    
    message UpdateDataRequest {
      string id = 1;
      string newData = 2;
    }
    
    message UpdateDataResponse {
      bool success = 1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在上面的示例中,我们定义了一个名为MyService的服务,其中包含了两个RPC方法:GetData和UpdateData。每个RPC方法都有对应的请求消息和响应消息。


    分享一个有趣的 学习链接:https://xxetb.xet.tech/s/HY8za

  • 相关阅读:
    首次引入大模型!Bert-vits2-Extra中文特化版40秒素材复刻巫师3叶奈法
    Java实现手机验证码登录和SpringSecurity权限控制
    在TensorFlow中使用GAN生成图像
    azkaban编译部署
    Spring Security 在登录时如何添加图形验证码
    【SpringBoot】请求与响应参数 IoC与DI 总结
    基于视觉AI的管道高后果区预警系统
    首发,看了这份美团资深架构师的spring源码总结后,才发现原来学习的思路都错了
    关于找暑期实习后的一些反思
    Spring中的拦截器HandlerInterceptor
  • 原文地址:https://blog.csdn.net/qq_29111047/article/details/134497112