2016-10-11 25 views
0

我想擴展Iterator特徵的功能。當在Rust中擴展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); 
         ^~~ 

這對我來說很陌生,因爲docs對於IntoIter<T>說它實現了Iterator<Item=T>

+0

這是一個麪點,但描述你有一個模塊'iter_statistics: :iter_statistics',這可能不是你的意思;不需要以它命名的文件內的'mod {}'。 –

+0

@ChrisEmerson Yup從我制定示例代碼時起就是一種冗餘:) – michael60612

回答

6

您所寫的impl只適用於特質對象(例如&mut Iterator<Item=f64>),而不適用於實現Iterator<Item=f64>的所有類型。你想寫一個通用的impl像這樣:

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

相關:[爲什麼我會在trait上實現方法而不是特性的一部分?](http://stackoverflow.com/q/ 155423分之34438755) – Shepmaster

3

你的實現是落後的。在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<Item = f64>

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