2017-06-27 16 views
-2

構造体内のHashMap内にいくつかの関数を格納しようとしています。コレクション内の関数への引数としてジェネリックを使用する

extern crate bson; 
extern crate serde; 

use std::sync::Arc; 
use std::collections::HashMap; 

type CBack = Fn(Vec<bson::Array>) -> Vec<u8> + Send + Sync + 'static; 

struct Struct { 
    cback_map: HashMap<String, Arc<CBack>> 
} 

fn main() {} 

私は、引数とクロージャの戻り値の型のためにジェネリックを使用して起動すると、コンパイラはオブジェクトがように大きさとされていない文句を開始: それは私がソリッドタイプを使用している場合に動作します。代わりに、私のマップに次の署名でクロージャを保持したいと考えています:

fn fun<'de, D, R>(_: D) -> R 
    where D: serde::Deserialize<'de>, R: serde::Serialize {} 

マップを正しく定義するにはどうしたらいいですか?

+2

_ "コンパイラが文句を言うようになった" _これらの苦情を提出すると、助けがはるかに簡単になります。 :)私はまた、最後の関数シグネチャがあなたが前に述べたものとはまったく異なっているので、主なコンテキストが何であるかも疑問です。 –

+0

私はコンパイラが文句を言うようになったと言いました。なぜなら、最初は大きさが違うからです。それは、同期や送信でなければ "+"で追加の特性を指定できないということです。このコンテキストでのジェネリックスなど –

+2

あなたはあなたの質問に**私たちを示していません**どのような種類のコードで問題を引き起こしているのですか?あなたがしたのは、*ジェネリックをいくつか追加した場合、それらのジェネリックがどのように追加されたか、または生成された正確な完全なエラーを表示せずに、いくつかのエラーを表示します。 – Shepmaster

答えて

1

マップが異種である必要がある場合、つまり異なるタイプのインスタンス化されたさまざまなバージョンの関数を保持する必要がある場合は、そのシグネチャを変更する必要があります。

タイプの場合、タイプがSizedの場合、この機能は動作します。しかし、すべて可能ですR s、コンパイラはそれぞれが異なる可能性があるため、サイズを知ることはできません。

これを機能させるには、Box<Serialize>または&Serializeのような特性オブジェクトを使用する必要があります。

他にも問題がある可能性があります。しかし、あなたの質問とコードの例は、私が上記で作ったものを超えて、 "物体が大きさにならない"ということに関連する観察をするのに十分ではありません。

+0

箱が助けになると思いますが、別の問題が生じます。逆直列化には、関数の引数を参照する1つの存続時間パラメータが必要です。間違いなく、マップ全体で1つの共有ライフタイムであってはいけません。これはリークです。各機能ごとにライフタイムを別々に宣言することは可能ですか? –

+1

_しかし、別の問題が出てくる_ _これが、[最小限の、完全で検証可能な例](https://stackoverflow.com/help/mcve)なしで誰でも効果的にあなたを助けることが難しい理由です。 –

関連する問題