区分Protobuf 3中缺失值和默认值

本文介绍了如何在 Protobuf 3 中区分缺失值和默认值,探讨了增加标识字段、字段含义和默认值区分、使用oneof、使用wrapper类型、允许proto3使用optional标签以及proto2和proto3结合使用等方法,同时分析了各方案的优缺点和JSON序列化效果。
摘要由CSDN通过智能技术生成

来自公众号:新世界杂货铺


这两天翻了翻以前的项目,发现不同项目中关于Protobuf 3缺失值和默认值的区分居然有好几种实现。今天笔者冷饭新炒,结合项目中的实现以及切身经验共总结出如下六种方案。

增加标识字段

众所周知,在Go中数字类型的默认值为0(这里仅以数字类型举例),这在某些场景下往往会引起一定的歧义。

is_show字段为例,如果没有该字段表示不更新DB中的数据,如果有该字段且值为0则表示更新DB中的数据为不可见,如果有该字段且值为1则表示更新DB中的数据为可见。

上述场景中,实际要解决的问题是如何区分默认值和缺失字段。增加标识字段是通过额外增加一个字段来达到区分的目的。

例如:增加一个has_show_field字段标识is_show是否为有效值。如果has_show_fieldtrueis_show为有效值,否则认为is_show未设置值。

此方案虽然直白,但每次设置is_show的值时还需设置has_show_field的值,甚是麻烦故笔者十分不推荐。

字段含义和默认值区分

字段含义和默认值区分即不使用对应类型的默认值作为该字段的有效值。接着前面的例子继续描述,is_show为1时表示展示,is_show为2时表示不展示,其他情况则认为is_show未设置值。

此方案笔者还是比较认可的,唯一问题就是和开发者的默认习惯略微不符。

使用oneof

oneof 的用意是达到 C 语言 union 数据类型的效果,但是诸多大佬还是发现它可以标识缺失字段。

message Status {
   
  oneof show {
   
    int32 is_show = 1;
  }
}
message Test {
   
    int32 bar = 1;
    Status st = 2;
}

上述proto文件生成对应go文件后,Test.StStatus的指针类型,故通过此方案可以区分默认值和缺失字段。但是笔者认为此方案做json序列化时十分不友好,下面是笔者的例子:

// oneof to json
ot1 := oneof.Test{
   
  Bar: 1,
  St: &oneof.Status{
   
    Show: &oneof.Status_IsShow{
   
      IsShow: 1,
    },
  },
}
bts, err := json.Marshal(ot1)
fmt.Println
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值