我正在尝试为有向图结构创建一个特征并提供一个非常基本的实现,但是遇到了编译器错误:
pub trait DiGraph<'a> {
type N;
fn nodes<T>(&'a self) -> T where T: Iterator<Item=&'a Self::N>;
fn pre<T>(&'a self, node: Self::N) -> T where T: Iterator<Item=&'a Self::N>;
fn succ<T>(&'a self, node: Self::N) -> T where T: Iterator<Item=&'a Self::N>;
}
struct SimpleNode {
pre: Vec<usize>,
succ: Vec<usize>,
}
pub struct SimpleDiGraph {
pub nodes: Vec<SimpleNode>
}
impl<'a> DiGraph<'a> for SimpleDiGraph {
type N = usize;
fn nodes<T=std::ops::Range<usize>>(&'a self) -> T {
return std::ops::Range { start: 0, end: self.nodes.len() };
}
fn pre<T=std::slice::Iter<'a,usize>>(&'a self, node: usize) -> T {
return self.nodes[node].pre.iter();
}
fn succ<T=std::slice::Iter<'a,usize>>(&'a self, node: usize) -> T {
return self.nodes[node].succ.iter();
}
}
Run Code Online (Sandbox Code Playgroud)
错误消息是:
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>`
Run Code Online (Sandbox Code Playgroud)
错误消息对我来说有点混乱 - 为什么类型参数会被期望作为返回值?这只是一种类型不匹配(例如由于生命周期)与错误的错误消息?
<T=std::ops::Range<usize>>不强迫T是std::ops::Range<usize>,它只是使其默认,如果它不知道用什么.
如果你只想要返回一个Range<usize>,那么Range<usize>用作返回类型; 根本没有理由拥有通用参数.你的代码现在有效地说的是这样的:
range<usize>."String拜托,我希望你回来."range<usize>!"如果你确实想调用者选择返回类型,那么你需要准备返回任何 T ......这几乎是不可能的,因为它可以从任何东西()到String到一个OpenGL渲染上下文.
在这种情况下,您实际想要做的是约束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() };
}
}
Run Code Online (Sandbox Code Playgroud)