在Rust中扩展Iterator trait时找不到方法

No method found when extending the Iterator trait in Rust

我正在尝试扩展Iterator特征的功能。

我的statistics/iter_statistics.rs

1
2
3
4
5
6
7
8
9
mod iter_statistics {
    pub trait IterStatistics: Iterator<Item = f64> {
        fn foo(&mut self) -> f64 {
            0.0
        }
    }

    impl IterStatistics for Iterator<Item = f64> {}
}

statistics/mod.rs

1
2
pub use self::iter_statistics::*;
mod iter_statistics;

最后在我的测试代码中,我有

1
2
3
4
5
6
use statistics::IterStatistics;

fn main() {
    let z: Vec<f64> = vec![0.0, 3.0, -2.0];
    assert_eq!(z.into_iter().foo(), 0.0);
}

运行测试时,我得到:

1
2
3
error: no method name `foo` found for type `std::vec::IntoIter<f64>` in the current scope
assert_eq!(z.into_iter().foo(), 0.0);
                         ^~~

这对我来说很奇怪,因为IntoIter<T>的文档说它实现了Iterator<Item=T>


您编写的impl仅适用于特征对象(例如&mut Iterator<Item=f64>),不适用于实现Iterator<Item=f64>的所有类型。您要像这样编写通用impl

1
impl<T: Iterator<Item=f64>> IterStatistics for T {}


您的实现落后。在Rust中进行编程时,您必须忘记OO继承和功能方面的原因。

What does trait D: B means in Rust?

这意味着D仅可用于已实现B的类型。它不是继承,而是约束。

When to use trait D: B then?

使用此约束的主要原因是,当您希望提供D方法的默认实现时,将需要B中的相关项目(特征,常量,方法)。

通常,您不想添加超出严格限制的限制,因为您的客户可能希望以您未预见的方式使用此特征。

一个例外是在将特征创建为"约束束"时,因此对于要实现的所有方法,您不必都键入T: SomeTrait + SomeOtherTrait + Send。此"束约束"应为空,然后;它毕竟不是功能特性,而只是一个"别名"。

So, how to extend Iterator?

首先声明一个新特征:

1
2
3
pub trait IterStatistics {
    fn foo(&mut self) -> f64;
}

然后对已经实现Iterator<Item = f64>

的所有类型实现它

1
2
3
4
5
6
7
impl< T > IterStatistics for T
    where T: Iterator<Item = f64>
{
    fn foo(&mut self) -> f64 {
        0.0
    }
}