问题
Proto3
is not as strict as Proto2
, and there are no required
or optional
fields, there are no custom default
values.
Given the following definition...
message Order {
enum Side {
BID = 0;
ASK = 1;
}
int64 time = 1;
double price = 2;
double volume = 3;
Side side = 4;
}
There are default values for any of those fields, after all now there are no rules of what you must or must not provide before you .build()
your object.
So the default for time
is 0
, price
is 0.0
and side
is BID
, if you print an instance where you did not provide one of the fields or provided the default value then runtime will treat it as it was never provided in both cases, so its not possible to determine if the value was manually set to BID
or it was taken as the default.
For example if we execute the following code (its kotlin)
Order.newBuilder()
.setPrice(1.0)
.setVolume(2.0)
.setSide(Order.Side.BID)
.build()
.apply { println(this) }
we will have this output
price: 1.0
volume: 2.0
at the very least this is annoying as when you print your proto objects using standard .toString()
or json printer you'll have this cropped output...
{ "price": 1.0, "volume": 2.0 }
{ "price": 1.0, "volume": 2.0, "side": "ASK" }
{ "price": 1.0, "volume": 2.0 }
{ "price": 1.0, "volume": 2.0, "side": "ASK" }
But what if your client does not necessarily care about default values and expects all fields to be present?
Question : is there a way to change this behaviour? at the very least how do we ensure that if value was set it is being shown?
Maybe there is a way to tell protoc
to generate different code (affecting defaults behaviour)...
回答1:
If you want Proto2's default value and set/unset behavior, you should switch back to Proto2. It is unlikely that Proto2 will go away any time soon as lots of code (including inside of Google) still depends on it, and it shares most of its implementation with Proto3. Think of proto2 vs. proto3 as an option (the exact option you're looking for, in fact) rather than a version change.
来源:https://stackoverflow.com/questions/37433955/proto3-setting-value-equal-to-default-is-not-recognised-in-runtime