web-dev-qa-db-ja.com

has_field()メソッドはprotobufのデフォルト値とどのように関連していますか?

デフォルト値とさまざまなプログラムインターフェイスで宣言されているhas_foo()メソッドの関係を特定しようとしています。特に、デフォルト値に明示的に設定されたフィールドと未設定の値の「違いを伝える」ことができる状況(ある場合)を特定しようとしています。

  1. フィールド(「Bar.foo」など)をデフォルト値(ゼロなど)に明示的に設定した場合、Bar :: has_foo()はそのデータ構造に対してtrueを返すことが保証されていますか? (これは、簡単な検査から、C++で生成されたコードに当てはまるように見えますが、それが保証されるわけではありません。)これが当てはまる場合、明示的に設定されたデフォルト値と未設定のデフォルト値を区別できますシリアル化前

  2. フィールドをデフォルト値(ゼロなど)に明示的に設定し、そのオブジェクトをシリアル化してネットワーク経由で送信した場合、値は送信されますか?そうでない場合は、明らかに、このオブジェクトを受け取るコードは、明示的に設定されたデフォルト値と未設定の値を区別できません。つまり、これら2つのケースを区別することはできませんシリアル化後-Bar :: has_foo()はどちらの場合もfalseを返します。

違いがわからない場合、「null許容」オプション値をエンコードする場合にprotobufフィールドをエンコードするための推奨テクニックは何ですか?いくつかのオプションが思い浮かびますが、どちらも素晴らしいとは思えません。(a)フィールドが設定されているかどうかを記録するブールフィールドを追加するか、(b)セマンティックにオプションのフィールドが必要な場合でも、「繰り返し」フィールドを使用します。このようにして、値なし(長さ0のリスト)と設定値(長さ1のリスト)の違いを知ることができます。

24
Edward Loper

以下は、「proto3」ではなく「proto2」構文に適用されます。

フィールドが設定されているかどうかの概念はProtobufのコア機能です。フィールドを値(任意の値)に設定すると、対応するhas_xxxメソッド must trueを返す必要があります。そうでない場合、APIにバグがあります。

フィールドを設定してからメッセージをシリアル化しない場合、そのフィールドの値は送信されません。受信側はメッセージを解析し、含まれている値を検出し、対応する「has_xxx」値を設定します。

これがワイヤーフォーマットでどのように実装されているかは、ここに文書化されています: http://code.google.com/apis/protocolbuffers/docs/encoding.html 。短いバージョンでは、メッセージはキーと値のペアのシーケンスとしてエンコードされ、明示的に設定されたフィールドのみがエンコードされたメッセージに含まれます。

デフォルト値は、未設定のフィールドを読み取ろうとした場合にのみ機能します。

31
JesperE