解决扩展特征的局限性

Ska*_*ade 8 iterator traits rust

具有对象安全特性FooFooExt为所有实例实现的(可能不安全的)扩展特征的模式Foo现在似乎成为标准.

https://github.com/rust-lang/rfcs/pull/445

对于我来说这是一个问题Iterator<A>,因为我有一个库来覆盖IteratorExt#last()旧迭代器特征的默认方法(底层库有一个有效的实现last()).现在这是不可能的,因为对于任何人来说A,总会有一个冲突的特质实施IteratorExt,即libcore已经为所有人提供的实施Iterator<A>.

iterator.rs:301:1: 306:2 error: conflicting implementations for trait `core::iter::IteratorExt` [E0119]

iterator.rs:301 impl<'a, K: Key> iter::IteratorExt<Vec<u8>> for ValueIterator<'a,K,Vec<u8>> {
iterator.rs:302   fn last(&mut self) -> Option<Vec<u8>> {
iterator.rs:303      self.seek_last();
iterator.rs:304      Some(self.value())
iterator.rs:305   }
iterator.rs:306 }
...
Run Code Online (Sandbox Code Playgroud)

现在,据我所知,我有两个选择:

  • 有我自己的特点和我自己的last()实现.IteratorExt除非仔细使用,否则这意味着它会导致冲突.last()如果使用版本from,这也有意外使用低效版本的危险IteratorExt.我放松了方便的访问IteratorExt.
  • 拥有自己的特征并以不同方式命名方法(seek_last()).缺点:我要求用户学习词汇,并总是喜欢我的方法而不是提供的方法IteratorExt.同样的问题:我想避免意外使用last().

我还缺少其他更好的解决方案吗?

Pao*_*lla 2

至于rustc 0.13.0-nightly (8bca470c5 2014-12-08 00:12:30 +0000)定义last()为您类型的固有方法应该有效。

#[deriving(Copy)]
struct Foo<T> {t: T}

impl<T> Iterator<T> for Foo<T> {
    fn next(&mut self) -> Option<T> { None }
}

// this does not work
// error: conflicting implementations for trait `core::iter::IteratorExt` [E0119]
// impl<T> IteratorExt<T> for Foo<T> {
//    fn last(mut self) -> Option<T> { None }
//}

// but this currently does
impl<T> Foo<T> {
    fn last(mut self) -> Option<T> { Some(self.t) }
}


fn main() {
    let mut t = Foo{ t: 3u };
    println!("{}", t.next())
    println!("{}", t.last()) // last has been "shadowed" by our impl
    println!("{}", t.nth(3)) // other IteratorExt methods are still available
}
Run Code Online (Sandbox Code Playgroud)

由于您不应该使用扩展特征作为通用边界(而只是提供附加方法),因此理论上这应该适合您的场景,因为您可以拥有自己的类型并将其放在impl同一个板条箱中。

您这种类型的用户将使用固有last方法而不是 上的方法IteratorExt,但仍然能够使用 上的其他方法IteratorExt