6

私はprotobufが初めてで、次の簡単な例を検討し始めました

message Entry {
  required int32 id = 1;
}

C++ コードで使用

#include <iostream>
#include "example.pb.h"
int main() {
  std::string mySerialized;
  {
    Entry myEntry;
    std::cout << "Serialization succesfull " 
              << myEntry.SerializeToString(&mySerialized) << std::endl;
    std::cout << mySerialized.size() << std::endl;
  }
  Entry myEntry;
  std::cout << "Deserialization successfull "
            << myEntry.ParseFromString(mySerialized) << std::endl;
}

「id」フィールドが必要な場合でも、設定されていないため、シリアライゼーション バッファのサイズは 0 (??) です。

メッセージを逆シリアル化すると、エラーが発生します。

[libprotobuf ERROR google/protobuf/message_lite.cc:123] Can't parse message of type "Entry" because it is missing required fields: id

それは正常な動作ですか?

フランチェスコ

ps-「id」を値0で初期化すると、動作が異なります

pps-SerializeToString関数は true をParseFromString返し、 は falseを返します

4

1 に答える 1

5

私はあなたの質問を正確に理解しているとは思いませんが、とにかく答えを試してみます. これが何らかの形で役立つことを願っています:)

はい、これは正常な動作です。requiredフィールドがメッセージにとって重要な場合にのみ追加してください。意味的には理にかなっています。(なぜ必須フィールドをスキップするのですか)。これを強制するために、protobuf はメッセージを解析しません。

番号 1 でマークされたフィールドが必須であり、has_id()メソッドが false を返していることがわかります。したがって、メッセージはまったく解析されません。

開発者ガイドでは、必須フィールドを使用しないことをお勧めします。

必須は永遠です フィールドを必須としてマークする場合は、十分に注意する必要があります。ある時点で、必須フィールドへの書き込みや送信を停止したい場合、そのフィールドをオプション フィールドに変更するのは問題があります。古いリーダーは、このフィールドのないメッセージは不完全であると見なし、意図せずに拒否またはドロップする可能性があります。代わりに、バッファに対してアプリケーション固有のカスタム検証ルーチンを作成することを検討する必要があります。Google の一部のエンジニアは、required を使用することは、良いことよりも悪いことの方が多いという結論に達しました。彼らはオプションと繰り返しのみを使用することを好みます。ただし、この見方は普遍的ではありません。

また

追加する新しいフィールドは、オプションまたは繰り返しにする必要があります。これは、「古い」メッセージ形式を使用してコードでシリアル化されたメッセージは、必要な要素が欠落していないため、新しく生成されたコードで解析できることを意味します。新しいコードが古いコードによって生成されたメッセージと適切にやり取りできるように、これらの要素に適切なデフォルト値を設定する必要があります。同様に、新しいコードで作成されたメッセージは、古いコードで解析できます。古いバイナリは、解析時に新しいフィールドを単純に無視します。ただし、不明なフィールドは破棄されず、メッセージが後でシリアル化される場合、不明なフィールドも一緒にシリアル化されます。そのため、メッセージが新しいコードに渡されても、新しいフィールドは引き続き使用できます。不明なフィールドの保存は現在 Python では利用できないことに注意してください

于 2013-03-12T12:29:32.717 に答える