模块的一揽子实施规则是什么?

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都是 ,CloneIterator,并且调用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)

游乐场

有人可以解释一下或链接相关文档,了解应用特征覆盖实现的规则与使特征本身可用的规则有何不同吗?

Kev*_*eid 1

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

因此,方法查找过程将大致执行以下操作:

  1. 我们从type 的*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