关于模块的全面实施的规则是什么?

What are the rules for blanket implementations regarding modules?

我一直在尝试查找有关 Rust 如何在涉及模块边界的情况下解决特征覆盖实现的文档,但没有找到与其直接相关的文档。

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

(Playground)

第二个片段只是对上面的稍作修改,即 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>())
}

(Playground)

有人可以解释一下或 link 相关文档,说明应用特征一揽子实施的规则与使特征本身可用的规则有何不同?

我没有对这里所有部分的参考手册的完整引用,但我看到这两种情况之间的区别是 ClonableIterator 在 [=45] 中 不可见=] mod helper(没有use super::ClonableIterator)。因此,在查找方法时,不会针对任意类型 查询特征,但(显然)它针对 dyn super::ClonableIterator,大概是因为不这样做会毫无意义地无益。

所以 method lookup procedure 将大致这样做:

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