对Foo
的所有实例实施对象安全特征FooExt
和(可能不安全)扩展特征Foo
的模式现在似乎已成为标准。
https://github.com/rust-lang/rfcs/pull/445
对于Iterator<A>
,这是一个问题,因为我有一个库来覆盖旧迭代器特征的默认方法IteratorExt#last()
(底层库有last()
的有效实现1}})。现在这是不可能的,因为对于任何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 }
...
现在,据我所知,我有两个选择:
last()
实现。如果导入IteratorExt
除非经过仔细使用,这意味着它会发生冲突。如果使用来自last()
的版本,这也有意外使用IteratorExt
的低效版本的危险。我无法轻松访问IteratorExt
。seek_last()
)。缺点:我要求用户学习词汇,并始终支持我的方法而不是IteratorExt
提供的方法。同样的问题:我想避免意外使用last()
。我还缺少其他更好的解决方案吗?
答案 0 :(得分: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
}
由于您不应该使用扩展特征作为通用边界(但只是为了提供其他方法),理论上这应该适用于您的场景,因为您可以拥有自己的类型及其impl
箱。
您的类型的用户将使用固有的last
方法而不是IteratorExt
上的方法,但仍然可以使用IteratorExt
上的其他方法。
答案 1 :(得分:0)
last
应移至Iterator
,而不是IteratorExt
。
IteratorExt
个对象时需要 Box<Iterator>
,以允许在其上调用泛型方法(例如map
),因为您无法在vtable中放置泛型方法。但是,last
不是通用的,因此可以放入Iterator
。