問題タブ [trait-objects]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
2 に答える
1813 参照

rust - Rustでボックス化された特性オブジェクトを値で渡す方法は?

私はいくつかのコードを書いていて、値を取るメソッドを持つ特性を持っていましたselfBox'd trait オブジェクトでこのメソッドを呼び出したい(Boxおよびその値を消費する)。これは可能ですか?もしそうなら、どのように?

コードに関しては、最小限の例は次の (不完全な) コードのようになります。

私の質問は、指定された署名を関数に入力して、返される値が'd 値consume_boxを呼び出すことによって取得される値になるようにする方法です。consumeBox

最初に書いていた

関数の本体として、これはまったく正しい考えではないことはわかっていBoxますが、その内容だけでなく、それを消費したいという事実を理解していないため、それが私が考えることができる唯一のものです. これはコンパイルされず、エラーが発生します。

タイプ dyn 消耗品の値を移動できません: dyn 消耗品のサイズは静的に決定できません

Rust を初めて使用する私にとって、これは少し驚きでした。self引数が C++ の右辺値参照と同様に渡されるのではないかと考えていました (これは本当に私が望んでいることです。C++ では、おそらく署名付きのメソッドによってこれを実装するでしょう)。virtual std::uint64_t consume() &&std::unique_ptr仮想デストラクタを介して移動元オブジェクトをクリーンアップできるようにします)が、Rustは本当に値渡しであり、引数を前の場所に移動していると思います-したがって、コードを拒否するのは合理的です.

Box問題は、 'd 特性オブジェクトを消費できる場所で、必要な動作を取得する方法がわからないことです。デフォルトの実装でトレイトにメソッドを追加しようとしましたが、vtable で何か便利なものが得られるかもしれないと考えました。

ただし、これによりエラーが発生します

特性Consumableをオブジェクトにすることはできません

型について言及すると、Box<dyn Consumable>これはそれほど驚くべきことではありません。引数の型が変化する関数をどう処理するかをコンパイラが判断するのSelfは奇跡的だったからです。

提供された署名を使用して関数を実装することは可能consume_boxですか?必要に応じて特性を変更することもできますか?


有用な場合、より具体的には、これはいくつかの数式の一種の表現の一部です。おもちゃのモデルは、大まかに次のような特定の実装になる可能性があります。

ここで、ほとんどの場合、物事は単純な古いデータです(ただし、ジェネリックのために、潜在的にその大きなブロックです)が、これをこれらの種類のものへのより不透明なハンドルを渡すことと互換性があるようにするため、欲求で作業できるようにしBox<dyn Consumable>ます。少なくとも言語レベルでは、これは私がやっていることの良いモデルです - これらのオブジェクトが所有する唯一のリソースはメモリの断片です (マルチスレッドとは何の関係もありませんし、自己参照的な悪ふざけもありません) - これはモデルは、私が持っているユースケースが、単にオブジェクトを読み取るのではなく、実装がオブジェクトを消費するのに役立つものであることを把握しておらず、「オープン」が必要であることを適切にモデル化していませんenumそれはツリーを直接表します) - したがって、参照渡しに書き直そうとするのではなく、値渡しについて尋ねているのはなぜですか。

0 投票する
1 に答える
176 参照

generics - Rcをキャストするにはどうすればよいですか> Rcへ>?

( implements )にキャストしようとしてRc<RefCell<Data>>いますが、一般的なメソッドでは不可能です:Rc<RefCell<dyn Interface>>DataInterface

非プリミティブ キャストでコンパイル エラーが発生しました。

遊び場

0 投票する
1 に答える
470 参照

rust - Rustでバインドされた再帰的特性を定義するには?

Boxまず、再帰構造を定義したい場合に使用できることを知っています。例えば、

しかし、これらの構造にテンプレートまたは trait オブジェクトを介してどのように特徴を作成できますか? が存在するため、次のfn append_next(...) -> Selfように特性オブジェクトを直接作成することはできません。

Option<Box<impl Linkable>>また、またはimpl Linkableの返品はできませんfn get_next(&self)

次に、汎用テンプレートを介して次の実装を試みましたが、機能しません。Tnew を構築するときに の型を再帰的に割り当てる必要があるためですLinkNode


最終的には、支援のための他の特性を作成することで、この方法で実装します。そして、それはうまく機能します。もう一度...他に良い方法はありますか?

ところで、上記の調査中に他にもいくつか質問があります。なぜRustはimpl Linkable砂糖を禁止するのBox<impl Linkale>ですか? そして、なぜ復帰impl Linkableが特性で禁止されているのですか?


Ibraheemの回答後に更新:

Ibraheemからの関連付けられた型の実装を除いて、このように動作することも問題ありません。コアとなるアイデアは、トレイトでの再帰的な型宣言を避けることです。

これは別の質問で言及されています: Rust でそれ自体の型パラメーターを持つ特性を定義できますか?