In proto3, all fields are "optional" (in that it is not an error if the sender fails to set them). But, fields are no longer "nullable", in that there's no way to tell the difference between a field being explicitly set to its default value vs. not having been set at all.
If you need a "null" state (and there is no out-of-range value that you can use for this) then you will instead need to encode this as a separate field. For instance, you could do:
message Foo {
bool has_baz = 1; // always set this to "true" when using baz
int32 baz = 2;
}
Alternatively, you could use oneof
:
message Foo {
oneof baz {
bool baz_null = 1; // always set this to "true" when null
int32 baz_value = 2;
}
}
The oneof
version is more explicit and more efficient on the wire but requires understanding how oneof
values work.
Finally, another perfectly reasonable option is to stick with proto2. Proto2 is not deprecated, and in fact many projects (including inside Google) very much depend on proto2 features which are removed in proto3, hence they will likely never switch. So, it's safe to keep using it for the foreseeable future.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…