johnsoncodehk 发表于 2022-3-11 09:51

Proto3使用指南

1.proto3 默认值


[*]ProtoBuf对象的get方法永远不会有null,如果没有设置,会生成对应的默认值
[*]如果属性值是一个message,pb会为这个属性生成一个hasXXX方法,可以用这个方法判断是否设置了这个属性
[*]对于其他属性,比如string,uint32等等,如果没有设置,get出来的将会是空值,比如string就是"",uint32就是0,此时无法区分是没有设置还是设置了默认值,需要业务自行约定,比如传一个"-1"等特殊的值标识
2.通过wrappers封装类解决proto3默认值和传参无法区分的问题

//比如说我的message字段中需要存在一个uint32类型的数据,0代表业务上的真实数据
//这时候可以用google.protobuf.UInt32Value封装类型来代替uint32
message xxxDTO {
    //...
    google.protobuf.UInt32Value source_type = 9;
    //...
}在rpcService中,可以通过getDefaultInstance的方式去判断服务调用方是没有传参数,还是传参和默认值相等
if (xxxDTO.getSourceType() == UInt32Value.getDefaultInstance()) {
    //...
}

[*]如果调用方未传,那么if条件成立,否则即便传参在数值上等于uint32的默认值0,也不会检查通过,代表服务端检测到用户传参,可以进行正常的业务判断和操作
[*]注意,不能使用xxxDTO.getXXX()==NULL的方式去判断,proto3相比于proto2去掉了很多NULL默认值改为default_instance
3.proto3踩坑汇总

3.1 message的默认值不是NULL,而是DEFAULT_INSTANCE

3.2 不支持一个proto文件中,多个枚举中定义相同的枚举常量名 比如以下定义会报错 IDLE is already defined in "xxx"

enum Enum1 {
    IDLE = 0;
    RUNNING = 1;
}

enum Enum2 {
    IDLE = 5;
    RUNNING = 6;
}3.3 proto标量值类型映射关系表



3.4 proto3常用基本类型默认值


[*]对于string,默认值是一个空string
[*]对于byte,默认值是一个空的bytes
[*]对于bool,默认值是false
[*]对于数值类型,默认值是0
[*]对于枚举类型,默认值是第一个定义的枚举值,且必须为0
总结不易,如果觉得对您有帮助,请点赞支持一下!
页: [1]
查看完整版本: Proto3使用指南