2016-10-12 36 views
9

我有一个特质有没有一种方法来实现遍历所有引用类型的迭代器的特征?

trait Foo<T> : Iterator<Item=T> { 
    fn bar(&mut self) -> f64; 
} 

我想通过它的所有引用类型(f64&'a f64&'a mut f64),因为在逻辑上也没关系,一旦实现这种特质的类型T(在我的情况f64) 。

我现在有

impl<T: Iterator<Item = f64>> Foo<f64> for T { 
    fn bar(&mut self) -> f64 { 
     // duplicated code 
    } 
} 

impl<'a, T: Iterator<Item = &'a f64>> Foo<&'a f64> for T { 
    fn bar(&mut self) -> f64 { 
     // duplicated code 
    } 
} 

impl<'a, T: Iterator<Item = &'a mut f64>> Foo<&'a mut f64> for T { 
    fn bar(&mut self) -> f64 { 
     // duplicated code 
    } 
} 

有没有办法做到这一点不重复的好办法?

+0

我不完全知道如何做到一切。如果不知道你究竟在干什么,你可能能够通过使用'Borrow'特性将重复代码移动到辅助函数中? [此围栏可能会提供一个可能的解决方案](https://play.rust-lang.org/?gist=296e500aa94741cb59af262454f5f413&backtrace=0)。 –

回答

7

您可以使用Borrow这个特质。如果您查看文档页面中的实施方案,前三项与此处相关:这意味着f64&'a f64&'a mut f64全部实施Borrow<f64>。您必须针对迭代器生成的每个值调用borrow方法以获得&f64

use std::borrow::Borrow; 

impl<T> Foo<T::Item> for T 
    where T: Iterator, 
      T::Item: Borrow<f64> 
{ 
    fn bar(&mut self) -> f64 { 
     unimplemented!() 
    } 
} 

顺便说一句,它并没有真正意义上定义的特征类型参数,并在同一时间把该类型参数和supertrait的相关类型之间的约束。 T类型只能有Iterator的一个实现,因此它只能有一个Foo的实现,尽管类型参数表明它可以实现许多不同的Foo<T>特征。因此,Foo上的类型参数是完全多余的(您可以只使用超类型的关联类型而不是类型参数)。因此,代码应该看起来更像这样:

use std::borrow::Borrow; 

trait Foo: Iterator { 
    fn bar(&mut self) -> f64; 
} 

impl<T> Foo for T 
    where T: Iterator, 
      T::Item: Borrow<f64> 
{ 
    fn bar(&mut self) -> f64 { 
     unimplemented!() 
    } 
} 
+0

我不得不在我的C#工作中在午餐时间在婴儿围栏中工作,所以我不能够快速思考到完全准确的语法。我很高兴我在一些正确的道路上走了一段路! –

+1

@SimonWhitehead你可以在集成测试运行的时候打开Rust代码。然后在单元测试运行。然后,虽然Intellisense绘制了曲线。 ;-) – Shepmaster

+1

@Shepmaster哈哈 - 我希望如此。在一天中的Rust和.NET之间的上下文切换有点刺耳;即使我在运行集成测试时有5分钟的上下文切换时间:P –

相关问题