Proto2 vs Proto3: 主な違い
proto2とproto3の構文の違いを比較:required/optionalフィールド、デフォルト値、enum、拡張機能、バージョン間の移行戦略。
Advanced Features
詳細な説明
Proto2 vs Proto3の比較
Proto3はいくつかのproto2機能を削除しデフォルトの動作を変更することで、protobuf言語を簡素化しました。違いの理解は、レガシースキーマの作業やバージョン間の移行に不可欠です。
// Proto2構文
syntax = "proto2";
message UserV2 {
required int32 id = 1;
required string name = 2;
optional string email = 3;
optional int32 age = 4 [default = 0];
repeated string tags = 5;
extensions 100 to 199;
}
// Proto3構文
// syntax = "proto3";
//
// message UserV3 {
// int32 id = 1;
// string name = 2;
// string email = 3;
// optional int32 age = 4;
// repeated string tags = 5;
// }
機能比較
| 機能 | Proto2 | Proto3 |
|---|---|---|
| フィールドプレゼンス | required、optional、暗黙 |
暗黙(すべてoptional)、明示的optionalキーワード |
| デフォルト値 | カスタムデフォルト可 | 固定デフォルトのみ(0、false、"") |
requiredキーワード |
サポート | 削除(有害と判断) |
| 不明フィールド | デフォルトで破棄 | デフォルトで保持 |
| Enumゼロ値 | 必須でない | ゼロ値必須 |
| 拡張機能 | サポート | 削除(代わりにAnyを使用) |
| グループ | サポート(非推奨) | 削除 |
| Mapフィールド | 利用不可 | 追加 |
| JSONマッピング | 基本 | 完全な標準マッピング |
requiredが削除された理由
proto2のrequiredキーワードは後方互換性バグの最大の原因として特定されました。フィールドがrequiredとマークされると、既存のすべてのパーサーを壊さずに削除することは不可能です。proto3はすべてのフィールドをoptionalとして扱い、スキーマの進化をより安全にします。
Proto3のフィールドプレゼンス
proto3では、スカラーフィールドは明示的に設定されたかどうかを追跡しません。値が0のフィールドは「ゼロに設定」または「まったく設定されていない」のいずれかの可能性があります。これらのケースを区別するには:
- ラッパー型を使用(
google.protobuf.Int32Value) optionalキーワードを使用(proto3.15+で再追加)- ブーリアンコンパニオンフィールドを使用(例:
bool has_age = 5;)
移行戦略
proto2からproto3に移行する際:
- すべての
requiredラベルを削除 - カスタム
default値を削除 extensionsを削除(google.protobuf.Anyまたはoneofで置換)- すべてのenumにゼロ値があることを確認
- 既存のシリアライズデータでテストして互換性を検証
ユースケース
新しいプロジェクトでどのprotobufバージョンを使用するかの決定、レガシーproto2スキーマのproto3への移行、またはバージョンによって決定される特定のprotobufパターンをコードベースが使用する理由の理解。