实现特征时“预期类型参数,找到结构”

2024-05-06

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

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

错误消息是:

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

错误消息让我有些困惑 - 为什么类型参数会被期望作为返回值?这是否只是类型不匹配(例如由于生命周期)并带有误导性的错误消息?


<T=std::ops::Range<usize>>不强迫T to be std::ops::Range<usize>,如果它不知道还可以使用什么,它只会导致它默认为该值。

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

  • “你可以选择任何你想要的返回类型!如果你不在乎,我会返回一个range<usize>."
  • “我希望你返回一个String, 请。”
  • "TOUGH你会得到一个range<usize>!"
  • “……但是你说……”
  • "我撒了谎!哇哈哈哈哈哈!"

If you actually想让调用者选择返回类型,那么就需要准备返回any T...这几乎是不可能的,因为它可能是来自() to String到 OpenGL 渲染上下文。

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

Edit: 只是要双重澄清:you不要选择通用参数中使用的类型,您的caller does.

直到现在我才注意到您在特征和实现中使用了不同的定义(不要这样做)。我假设你是什么really试图做的是说“这个方法返回某物这可以用作Iterator,但每个impl可以选择不同的类型。”cannot使用泛型来做到这一点。

你什么want是特征的关联类型,如下所示:

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() };
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实现特征时“预期类型参数,找到结构” 的相关文章

随机推荐