私は外部シリアル化フォーマットを表す構造体Foo
を持っています。 Foo
には数十のフィールドがあり、それ以上は常に追加されます。幸いなことに、すべての新しいフィールドには分かりやすいデフォルト値が保証されています。プライベートフィールドを持つRust構造体のパブリックフィールドを更新する
錆がデフォルト値を使用して構造体を作成し、いくつかの選択された値の更新のための素敵な構文があります。同様に
Foo {
bar: true,
..Default::default()
}
を、私たちは、この構造体」のアイデアを表現することができ、将来のバージョンで複数のフィールドを有することができます"タイプPhantomData
のプライベートフィールドを使用しています。
しかし、我々はこれら二つのイディオムを組み合わせた場合、我々はエラーを取得:
use std::default::Default;
mod F {
use std::default::Default;
use std::marker::PhantomData;
pub struct Foo {
pub bar: bool,
phantom: PhantomData<()>,
}
impl Default for Foo {
fn default() -> Foo {
Foo {
bar: false,
phantom: PhantomData,
}
}
}
}
fn main() {
F::Foo {
bar: true,
..Default::default()
};
}
は、これは私たちにエラーを与える:私たちは「ので
論理的error: field `phantom` of struct `F::Foo` is private [--explain E0451]
--> <anon>:23:5
|>
23 |> F::Foo {
|> ^
、私は、これは動作するはずと主張パブリックフィールドを更新するだけで、有用なイディオムになります。代替は、次のようなものをサポートすることです:
Foo::new()
.set_bar(true)
...何十ものフィールドで面倒になるでしょう。
この問題を回避するにはどうすればよいですか?
'phantom'の名前を' __phantom'に変更し、公開し、 '#[doc(hidden)]'にします。実際の例:['std :: io :: ErrorKind :: __ Nonexhaustive'](https://doc.rust-lang.org/src/std/up/src/libstd/io/error.rs.html#162- 168) – mcarton
@mcarton 'std'は' __NoneXhaustive'変種が不安定であると宣言することができる点で少し特殊です。安定したRustを使用している場合、呼び出し元は文字通り使用できません。この同じトリック(私が間違いなく行うことです)を採用している図書館の作家は、慣例に頼らなければなりません。 (私は実際には本当の問題ではないと思いますが、私はちょうどペダントです。) – BurntSushi5
@emk私は** PhantomDataについて学んでいました**。この便利な例をありがとう! – ljedrz