web-dev-qa-db-ja.com

proto3にカスタムのデフォルト値がないのはなぜですか?

プロトコルバッファのproto2バージョンでは、メッセージ要素のデフォルト値を指定できます。

optional double scaling_factor = 3 [default = 1.0];

protoでこれが不可能になったのはなぜですか?これは、ラッパーコードを記述する必要なく、回線上の追加バイトを節約するためのすばらしい機能であると考えています。

35
Daniel Pauli

私の理解では、proto3はフィールドの存在を検出できなくなり、非ゼロのデフォルト値をサポートしなくなりました。これにより、アクセサーメソッドを生成することなく、さまざまな言語で「プレーンな古い構造体」の観点からprotobufを実装しやすくなるためです。これは、これらの言語でProtobufを使いやすくするものと考えられています。

(私は個人的に、アクセサとプロパティを欠いている言語はあまり良い言語ではないと考えており、protobufはそれらに合わせて設計するべきではありませんが、それはもはや私のプロジェクトではありません。)

48
Kenton Varda

自動生成されたファイル.pb.ccには、次のような場所がいくつかあります。

if (this->myint() != 0) {

このようなものはほとんどありません:

myint_ = 0;

だから、なぜデフォルト値を有効にして生成しないのですか?

static ::google::protobuf::int32 myint_defaultvalue = 5;

...
if (this->myint() != myint_defaultvalue) {
...

...
myint_ = myint_defaultvalue;
...

代わりに?

1
Ilyan

これはあなたの質問に直接答えるのではなく回避策ですが、wrappers.protoオプション値を使用し、これがデフォルト値であるかどうかを絶対に知る必要があるときにプログラムでデフォルト値を設定することに気付きました明示的に設定します。

生成されたコード自体の代わりにコードが値を強制する必要があることは最適ではありませんが、少なくとも両方を所有している場合は、特に見ているときに値がデフォルトまたは明示的に設定されているかどうかがわからない代わりに実行可能な選択肢ですfalseに設定されたブール。

これがワイヤ上のバイトにどのように影響するかはわかりません。私が使用した例では、メッセージの長さは設計上の制約ではありませんでした。

プロトファイル

import "google/protobuf/wrappers.proto";

google.protobuf.BoolValue optional_bool = 1;

Javaコード

//load or receive message here
if( !message.hasOptionalBool() )
    message.setOptionalBool( BoolValue.newBuilder().setValue( true ) );
0
Evan