【问题标题】:No method found when extending the Iterator trait in Rust在 Rust 中扩展 Iterator 特征时找不到方法
【发布时间】:2016-10-11 01:19:57
【问题描述】:

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

我的statistics/iter_statistics.rs

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

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

最后在我的测试代码中

use statistics::IterStatistics;

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

当我运行测试时,我得到:

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

这对我来说很奇怪,因为 docsIntoIter&lt;T&gt; 说它实现了 Iterator&lt;Item=T&gt;

【问题讨论】:

  • 这是一个侧面,但如上所述,您有一个模块iter_statistics::iter_statistics,这可能不是您的意思;在以它命名的文件中不需要mod {}
  • @ChrisEmerson 是的,这是我在编写示例代码时的冗余:)

标签: rust


【解决方案1】:

您编写的impl 仅适用于特征对象(例如&amp;mut Iterator&lt;Item=f64&gt;),不适用于所有实现Iterator&lt;Item=f64&gt; 的类型。你想像这样写一个通用的impl

impl<T: Iterator<Item=f64>> IterStatistics for T {}
【解决方案2】:

你的实现是落后的。使用 Rust 编程时,您必须忘记 OO 继承和能力方面的原因。

trait D: B 在 Rust 中是什么意思?

这意味着D 只能用于已经实现B 的类型。这不是继承,而是约束

那么什么时候使用trait D: B

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

通常,您不希望添加比严格必要的更多的约束,因为您的客户可能希望以您未预见到的方式使用此特征。

一个例外是在将特征创建为“约束捆绑”时,因此您没有为您正在实现的所有方法提供T: SomeTrait + SomeOtherTrait + Send 类型。那么这个“约束束”应该是空的;毕竟它不是功能特征,只是一个“别名”。

那么,如何扩展Iterator

首先声明一个新特征:

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

然后为所有已经实现Iterator&lt;Item = f64&gt;的类型实现它:

impl<T> IterStatistics for T
    where T: Iterator<Item = f64>
{
    fn foo(&mut self) -> f64 {
        0.0
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-11
    • 2012-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多