sou*_*rce 6 generics traits rust trait-objects
我一直在尝试查找有关 Rust 如何在涉及模块边界的情况下解决特征包实现的文档,但没有找到与之直接相关的内容。
让我们考虑一个包含两个相似但略有不同的代码片段的示例:
第一个代码片段编译得很好,但会遭受无限的运行时递归。ClonableIterator发生这种情况是因为for 的全面实现T: Iterator+Clone与 which is 相匹配Box<dyn ClonableIterator<'a>>,这要归功于我们手动实现Clone和nowBox的全面实现。IteratorIterator+Clone
//the trait itself, with the indirection to call box_clone on the base type
trait ClonableIterator<'a>: Iterator<Item = &'a u32> + 'a {
fn box_clone(&self) -> Box<dyn ClonableIterator<'a>>;
}
//The blanket implementation of the trait for all clonable iterators
impl<'a, T: Iterator<Item = &'a u32> + Clone + 'a> ClonableIterator<'a> for T {
fn box_clone(&self) -> Box<dyn ClonableIterator<'a>> {
Box::new(self.clone())
}
}
//Clone for the box. Does not work
impl<'a> Clone for Box<dyn ClonableIterator<'a>> {
fn clone(&self) -> Self {
(*self).box_clone()
}
}
fn main() {
let input = vec![1,2,3,4,5];
let iter1 : Box<dyn ClonableIterator> = Box::new(input.iter());
let iter2 : Box<dyn ClonableIterator> = Box::new(iter1.clone().filter(|&&x| x%2 == 0));
println!("{} {}", iter1.sum::<u32>(), iter2.sum::<u32>())
}
Run Code Online (Sandbox Code Playgroud)
(游乐场)
第二个片段只是对上面的内容进行了轻微修改,即特征的实现Clone已移至子模块。然而,它正在发挥作用,并且正在做人们所期望的事情。创建的 Trait 对象ClonableIterator都是 ,Clone和Iterator,并且调用clone()它们的方法会创建装箱迭代器的实际副本。方法 和 都
可以直接在 上调用,并且从它创建的迭代器也是,因此可以从它们创建特征对象。Iteratorclone()Box<dyn ClonableIterator>Clone+IteratorClonableIterator
//the trait itself, with the indirection to call box_clone on the base type
trait ClonableIterator<'a>: Iterator<Item = &'a u32> + 'a {
fn box_clone(&self) -> Box<dyn ClonableIterator<'a>>;
}
//The blanket implementation of the trait for all clonable iterators
impl<'a, T: Iterator<Item = &'a u32> + Clone + 'a> ClonableIterator<'a> for T {
fn box_clone(&self) -> Box<dyn ClonableIterator<'a>> {
Box::new(self.clone())
}
}
//a helper module, to prevent the above blanket implementation from matching
//the Box<dyn super::ClonableIterator<'a>>.
//I can't find the documentation how this works, but it does work.
mod helper {
impl<'a> Clone for Box<dyn super::ClonableIterator<'a>> {
fn clone(&self) -> Self {
(*self).box_clone()
}
}
}
fn main() {
let input = vec![1,2,3,4,5];
let iter1 : Box<dyn ClonableIterator> = Box::new(input.iter());
let iter2 : Box<dyn ClonableIterator> = Box::new(iter1.clone().filter(|&&x| x%2 == 0));
println!("{} {}", iter1.sum::<u32>(), iter2.sum::<u32>())
}
Run Code Online (Sandbox Code Playgroud)
(游乐场)
有人可以解释一下或链接相关文档,了解应用特征覆盖实现的规则与使特征本身可用的规则有何不同吗?
我在这里没有对所有部分的参考手册的完整引用,但是我看到这两种情况之间的区别在(没有)中ClonableIterator不可见。因此,在查找方法时,不会针对任意类型咨询该特征,但(显然)它是针对 的,大概是因为不这样做是毫无帮助的。 mod helperuse super::ClonableIteratordyn super::ClonableIterator
因此,方法查找过程将大致执行以下操作:
*self显式取消引用开始。
&Box<dyn CloneableIterator<'a>>Box<dyn CloneableIterator<'a>>box_clone()?不。box_clone()?
ClonableIterator在同一范围内声明),因此调用了一个。Box<dyn CloneableIterator<'a>>以获得dyn CloneableIterator<'a>.
box_clone()?不。box_clone()?是的,显然CloneableIterator该类型无条件可见dyn。