2016-11-21 1 views
1

私は1つの非常に基本的なimplementatioを有向グラフ構造のための形質を作成し、提供しようとしていますが、コンパイルエラーに実行しています「期待されるタイプのパラメータは、構造体を発見しました」 :実装トレイト

error[E0308]: mismatched types 
--> digraph.rs:21:16 
| 
21 |   return std::ops::Range { start: 0, end: self.nodes.len() }; 
|    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found struct `std::ops::Range` 
| 
= note: expected type `T` 
= note: found type `std::ops::Range<usize>` 

error[E0308]: mismatched types 
--> digraph.rs:24:16 
| 
24 |   return self.nodes[node].pre.iter(); 
|    ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found struct `std::slice::Iter` 
| 
= note: expected type `T` 
= note: found type `std::slice::Iter<'_, usize>` 

error[E0308]: mismatched types 
--> digraph.rs:27:16 
| 
27 |   return self.nodes[node].succ.iter(); 
|    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found struct `std::slice::Iter` 
| 
= note: expected type `T` 
= note: found type `std::slice::Iter<'_, usize>` 

エラーメッセージは多少混乱します。なぜ型パラメータが戻り値として期待されるのですか?これは誤解を招くエラーメッセージが表示された場合の型の不一致(生存期間など)ですか?

答えて

7

<T=std::ops::Range<usize>>は、Tstd::ops::Range<usize>に強制しません。それ以外の使用方法がわからない場合は、デフォルトになります。

Range<usize>を返したい場合は、戻り値の型としてRange<usize>を使用してください。ジェネリックパラメータを持つ理由は全くありません。どのようなコードが効果的に今言っていることは、このようなものです:

  • 「あなたが望む任意の戻り値の型を選ぶことができますが、気にしない場合、私はrange<usize>を返しますよ!。」
  • Stringを返品してください。」
  • "TOUGHあなたはrange<usize>を取得しています!"
  • "...しかし、あなたが言った..."
  • "を私は!MUAHAHAHAHAHAを嘘をついた!"

をあなた実際は、あなたがする必要がある、呼び出し側は戻り値の型を選択します()StringからOpenGLレンダリングコンテキストになる可能性があるため、ほとんど不可能なので、anyTを返すように準備してください。

この場合、は実際にとしたいのですが、あるタイプの構築機能を実装する必要があるいくつかの特性には、Tが制約されています。 Defaultはその一例です。

編集:だけ二重に明確にする:あなたはあなた、発信者はない、一般的なパラメータで使用されるタイプを選択するために得ることはありません。

私は今、あなたが特性と実装で異なる定義を使用していることに気付きませんでした(そうしないでください)。私はあなたがの本当にであると仮定しているとします。「このメソッドは何かを返します。これはIteratorとして使用できますが、それぞれimplは別のタイプを選ぶことができます。あなたはできませんジェネリックでこれを行う。あなたは私の正しくつもり推測

pub trait DiGraph<'a> { 
    type Nodes; 
    fn nodes(&'a self) -> Self::Nodes; 
} 

pub struct SimpleNode { 
    pre: Vec<usize>, 
    succ: Vec<usize>, 
} 

pub struct SimpleDiGraph { 
    pub nodes: Vec<SimpleNode> 
} 

impl<'a> DiGraph<'a> for SimpleDiGraph { 
    type Nodes = std::ops::Range<usize>; 

    fn nodes(&'a self) -> Self::Nodes { 
     return std::ops::Range { start: 0, end: self.nodes.len() }; 
    } 
} 
+0

おかげで、良い説明:あなたはがそうのように、特性に関連するタイプである必要

。しかし、あなたのケースでは、ノードは、それがノードについての仮定を行うことができないので、二重字に動作する任意の機能は多くを行うことができるようにするつもりはないことを意味何でも、することができます。だから、私がしたいのは、NをイテレータにするようにNodesを制限することです(私の例ではusizeですが、呼び出し元によって定義されます)。 SimpleDiGraphは常に範囲オブジェクトを返すようにするために、私は幸せなんだけど、他の構造体は、有向グラフがNの上にそれを達成するための任意の方法を他のイテレータを返すことができるはず実装しますか? –

+0

は、私はそれを考え出したと考えて、あなたが実際にそのよう _typeののNodeIteratorとして形質種類を、制限することができますように見える:イテレータの; _ トリックを行うべきです。今、生涯の問題を理解するだけです。 –