关于模块的一揽子实现的规则是什么



我一直在努力寻找关于Rust如何在涉及模块边界的情况下解决特征毯实现的文档,但没有发现太多与之直接相关的内容。

让我们考虑一个具有两个相似但略有不同的代码片段的示例:
第一个代码段编译得很好,但会遇到无限的运行时递归。这是因为T: Iterator+CloneClonableIterator的一揽子实现与Box<dyn ClonableIterator<'a>>相匹配,这要归功于我们手动实现的CloneBoxIterator的一揽子实现,现在是Iterator+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>())
}

(游乐场(

第二个片段只是对上述内容的一个轻微修改,即Clone特性的实现已移至子模块。然而,它正在发挥作用,并按照人们的期望行事。ClonableIterator创建的Trait对象是CloneIterator,对它们调用clone()方法会创建装箱迭代器的实际副本
Iterator方法和clone()都可以直接在Box<dyn ClonableIterator>上调用,从中创建的迭代器又是Clone+Iterator,因此可以从中创建ClonableIterator特征对象。

//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>())
}

(游乐场(

请有人解释或链接相关文档,说明应用特性一揽子实现的规则与特性本身可用的规则有何不同?

我没有完整引用参考手册的所有部分,但我看到这两种情况之间的区别是ClonableIteratormod helper中不可见(没有use super::ClonableIterator(。因此,在查找方法时,对于任意类型,不会参考该特性,但(显然(对于dyn super::ClonableIterator,可能是因为不这样做毫无帮助。

因此,方法查找过程大致如下:

  1. 我们从*self开始,它是Box<dyn CloneableIterator<'a>>类型的&Box<dyn CloneableIterator<'a>>的显式解引用。
    • 这有一个名为box_clone()的固有方法吗?没有
    • 任何可见特征都有一个名为box_clone()的方法吗?
      • 在第一个程序中,是(ClonableIterator在同一范围内声明(,因此调用了一个
      • 在第二个程序中,没有,所以继续
  2. 对CCD_ 28进行去引用,得到CCD_。
    • 这有一个名为box_clone()的固有方法吗?没有
    • 任何可见特征都有一个名为box_clone()的方法吗?是的,显然CloneableIterator对于dyn类型是无条件可见的

最新更新