web-dev-qa-db-ja.com

Protobuf 3がメッセージのすべてのフィールドをオプションにしたのはなぜですか?

Protobufの構文3により、すべてのフィールドがオプションになり、前のproto2構文のキーワードrequiredおよびoptionalが削除されました。 開発者からのコメントを読む これは、バイナリの前方/後方互換性を強化するために行われたようです。

しかし、私にとっては、パッケージ名をバージョン管理するだけで適用できます。たとえば、com.example.messages.v1そして、クライアントが理解できるデシリアライザを実装できるようにします。同時に、ソフトウェアエンジニアリングの観点から有用なタイプとして記述されている一部の契約を削除します。例えば私が持っている場合

message Location {
   double latitude = 1;
   double longitude = 2;
}

Proto3では、必須フィールドの1つを提供しないことにより、半分バックアップされているが完全に有効なLocationを作成できます。

クライアント間でデータを交換するためのスキーマベースのシリアル化形式を作成する場合、それは大きな欠点ではありませんか?余分な検証コードを各クライアントに移動して、すべての必須フィールドに有効な値があることを確認するほうが悪くありませんか?

16
tonicebrian

proto3は、numberの変更を(私が理解しているように)クロスプラットフォームのシナリオではるかに使いやすくすることを目的としています。 「割り当てられている」と「割り当てられていないがデフォルト値を報告する」の明示的な追跡は、一部のターゲットプラットフォームでvery実装するのが難しい場合があり、さらに使い方がわかりにくい。そのため、proto3はより単純なアプローチを採用しています。

  • implicitのデフォルト値は、自然なゼロ値(数値/列挙型)、false(ブール値)、または空の文字列(文字列)です。
  • only暗黙のデフォルトが許可されます。他のデフォルト値は許可されていません
  • フィールドにそのデフォルト値がある場合、シリアル化されません。明示的にゼロに割り当てられているか、false /空の文字列であるか、割り当てられていないかは関係ありません。
  • このため、「明示的にゼロ値が割り当てられている」と「値が割り当てられていない」は同一に見えるため、「必須」という概念はありません。

Proto3では、必須フィールドの1つを提供しないことで、ハーフバックアップされた完全に有効なLocationを作成できます。

その他の値はゼロです。明示的に明示的にゼロに割り当てなかったという事実は意味がありません。これが望ましいかどうかはあなた次第ですが、私にとっては理にかなっており、さまざまなプラットフォームで多くの「新しいオブジェクト/構造体を初期化する」ことが機能します。

余分な検証コードを各クライアントに移動して、すべての必須フィールドに有効な値があることを確認するほうが悪くありませんか?

検証するものは何もありません!レイアウトは、ゼロの値が明示的に割り当てられた場合とまったく同じです。それが合法であれば、合法です。違法な場合(ゼロは意味をなさないため)、違法です。しかし、それが明示的であるか暗黙的であるかは違法です。関連する検証の量は変わりません。

クライアント間でデータを交換するためのスキーマベースのシリアル化形式を作成する場合、それは大きな欠点ではありませんか?

通常はありません。特に、スキーマバージョンが明示的であるためです。 proto2を使用する場合:proto2を使用します。自動的に変更されるものはありません。

15
Marc Gravell