"期望的类型参数,找到struct"实施特质时

时间:2016-11-21 04:10:33

标签: rust

我正在尝试为有向图结构创建一个特征并提供一个非常基本的实现,但是遇到了编译器错误:

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>`

错误消息是:

{{1}}

错误信息对我来说有点混乱 - 为什么要将类型参数作为返回值?这只是一种类型不匹配(例如由于生命周期)和错误的错误消息吗?

1 个答案:

答案 0 :(得分:7)

<T=std::ops::Range<usize>>并不强迫T成为std::ops::Range<usize>,如果它不知道还有什么可以使用,则只会导致它默认为

如果您只想返回Range<usize>,请使用Range<usize>作为返回类型;根本没有理由拥有通用参数。你的代码现在有效地说的是这样的:

  • &#34;您可以选择任何您想要的返回类型!如果您不在乎,我将返回range<usize>。&#34;
  • &#34;我希望你能回复String。&#34;
  • &#34; TOUGH 您正在获得range<usize>!&#34;
  • &#34; ...但你说...&#34;
  • &#34; 我骗了! !MUAHAHAHAHAHA &#34;

如果实际希望调用者选择返回类型,那么您需要准备好返回任何 T ...这几乎是不可能的,因为它可以是从()String到OpenGL渲染上下文的任何内容。

在这种情况下,实际想要做的是将T约束到某些要求类型实现某种构造函数的特征。 Default是一个例子。

修改:只是要加倍澄清:不能选择通用参数中使用的类型,来电

直到现在我才注意到你在特质和实施中使用了不同的定义(不要这样做)。我假设您真正尝试做的事情是说&#34;此方法会返回某些可用作Iterator的内容,但每个impl可以选择不同的类型。&#34;你不能用泛型来做这件事。

您想要的是特质上的关联类型,如下所示:

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() };
    }
}