What's the difference between using an Enum and a oneof kind in protobuf3? As far as I can tell, an Enum restricts the field to be one of a predefined set of values, but so does the oneof kind.
1 Answers
Enums are named numbers. You define the names in the enum definition and assign them a value. An enum should always have the value zero it it's set.
enum State {
A = 0;
B = 1;
C = 2;
}
Next you can use this enum in any of your message
message Update {
State currentState = 1;
State previousState = 2;
}
A oneof is something very different. It allows you to send different types but only allocate limited memory for them. This as you can only set one of those types at a time. This is similar to an union
in C/C++ or a std::variant
as of C++17.
Take this example in which we have a message, a integer and double defined in our oneof.
// The message in our oneof
message someMsg {
// Multiple fields
}
// The message holding our oneof
message msgWithOneof {
oneof theOneof {
someMsg msg = 1;
int32 counter = 2;
double value = 3;
}
// Feel free to add more fields her of before the oneof
}
You are only able to set msg
, counter
or value
at one time. If you set another this will clear the other field.
Assuming an C/C++ implementation the largest field will determine the amount of memory allocated. Say someMsg
is the largest, setting a integer or double will not be a problem as they fit in the same space. If you not use a oneof the total memory allocated would be the sum of sizeof(someMsg) + sizeof(int32) + sizeof(double)
.
There is some overhead to keep track which field has been set. In the google C++ implementation this is a bit in the presence variable. This is similar to fields which are marked optional.

- 1,405
- 6
- 32
-
2Minor addition to "different types", it also allows you to represent the same *type*, but with different semantic meaning - for example, `msgWithOneof.theOneof` could also have an additional `double valueDelta = 4;` and `someMsg criticialMessage = 5;` (but at most one of the values in `theOneof` can have a value at any one time) – Marc Gravell Sep 15 '21 at 07:14
-
@MarcGravell Excellent remark. It is indeed very well possible to repeat the same type multiple times in a oneof yet allocate memory only once. – Bart Sep 15 '21 at 07:23