grpc protobuf 中缺失值和默认值

前言

关于默认值的问题,先用以下简单的 java 代码示例说明一下:

public class Variable {
   private int intNum;

    public int getIntNum() {
        return intNum;
    }

    public void setIntNum(int intNum) {
        this.intNum = intNum;
    }
}
public class MainServer {
    public static void main(String[] args) {
        Variable var = new Variable();
        System.out.println("没set时,intNum默认值为:" + var.getIntNum());
        var.setIntNum(0);
        System.out.println("set之后,intNum的值是:" + var.getIntNum());
    }
}

输出:

没set时,intNum默认值为:0
set之后,intNum的值是:0

输出的都是 0,一个是默认值( java 中 int 类型不赋值的话默认为 0),一个是通过 setIntNum 方法给它赋值为 0

在上面的代码中你可以很容易的知道 var 中的 intNum 是默认值还是不是默认值。

那如果是微服务呢,A微服务通过网络把 var 对象传给 B 微服务,B 微服务从 var 中得到的 intNum 是 0,B 微服务是区分不出是不是默认值的。

举个例子:
如果客户输入一个值 ,A 微服务就调用 setIntNum 方法赋值给 intNum ,然后把 var 通过网络把 var 对象传给 B 微服务,B 微服务就把用户的输入存到数据库。

但是如果客户输入 0 这个时候 B 微服务是并不知道这个 0 是默认值还是调用 setIntNum 方法赋值的,所以 B 微服务就不知道要不要把这个 0 存入数据库。

Protobuf 里面也是和上面的例子一样的。

一 、protobuf 默认值说明

Protobuf 是目前非常主流的二进制序列化格式,GRPC 默认使用 Protobuf v3 格式。
proto里没有设置的参数是会有默认值的。

假设 proto 文件里如下:

message Account {
		string name = 1
		int  profit_rate = 2
}

profit_rate 的默认值会是 0,所以就算前端 不传参数或者不给它复制也会有默认值 0,代码里无法区分它是默认值 0 还是赋值给的 0 。

二、 使用 oneof

为了避免上面的问题 proto 文件里可以使用 oneof :

message Account {
	string name = 1;
	oneof profit_rate {	
			int  profitrate = 2;
	}
}

这样,在 Java 中,可以用 XxxCase() == XxxCase.XXX_NOT_SET 或者 XxxCase().getNumber == 0 判断是否设置 oneof ,以此来判断是不是赋值的而不是默认值。


//如果设置了值则获取值 (即如果前端传了值才进入if,没传值用的默认值的话就不进if )
if (Account.CheckProfitrateCase.PROFITRATE == account.getCheckProfitrateCase()) {
          int profitrate = account.getProfitrate();
}

其他类型的默认值如下:
对于字符串,默认值为空字符串。
对于字节,默认值为空字节。
对于布尔值,默认值为false。
对于数字类型,默认值为零。
对于枚举,默认值为第一个定义的枚举值,必须为0。

三、四种 grpc 模式示例

如果你对 grpc 感兴趣,可以看下我用 springboot 写的 grpc 示例,github地址:grpc-spring-boot-demo
里面分别介绍了四种 grpc 模式:简单 grpc、服务端流式 grpc、客户端流式 grpc、双向流式 grpc


参考文章:
区分 Protobuf 中缺失值和默认值
语言指南(proto3)
集成grpc,普通对象与grpc对象转换

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值