关于模块的全面实施的规则是什么?
What are the rules for blanket implementations regarding modules?
我一直在尝试查找有关 Rust 如何在涉及模块边界的情况下解决特征覆盖实现的文档,但没有找到与其直接相关的文档。
让我们考虑一个包含两个相似但略有不同的代码片段的示例:
第一个是编译得很好的代码,但会遇到无限的运行时递归。发生这种情况是因为 T: Iterator+Clone
的 ClonableIterator
的一揽子实施与 Box<dyn ClonableIterator<'a>>
匹配,这要归功于我们手动实施 Clone
和 Box
的一揽子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>())
}
第二个片段只是对上面的稍作修改,即 Clone
特性的实现已移至子模块。但是,它正在工作并且正在做人们期望的事情。 ClonableIterator
创建的 Trait 对象是 Clone
和 Iterator
,对它们调用 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>())
}
有人可以解释一下或 link 相关文档,说明应用特征一揽子实施的规则与使特征本身可用的规则有何不同?
我没有对这里所有部分的参考手册的完整引用,但我看到这两种情况之间的区别是 ClonableIterator
在 [=45] 中 不可见=] mod helper
(没有use super::ClonableIterator
)。因此,在查找方法时,不会针对任意类型 查询特征,但(显然)它针对 dyn super::ClonableIterator
,大概是因为不这样做会毫无意义地无益。
所以 method lookup procedure 将大致这样做:
- 我们从
*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
类型是无条件可见的。
我一直在尝试查找有关 Rust 如何在涉及模块边界的情况下解决特征覆盖实现的文档,但没有找到与其直接相关的文档。
让我们考虑一个包含两个相似但略有不同的代码片段的示例:
第一个是编译得很好的代码,但会遇到无限的运行时递归。发生这种情况是因为 T: Iterator+Clone
的 ClonableIterator
的一揽子实施与 Box<dyn ClonableIterator<'a>>
匹配,这要归功于我们手动实施 Clone
和 Box
的一揽子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>())
}
第二个片段只是对上面的稍作修改,即 Clone
特性的实现已移至子模块。但是,它正在工作并且正在做人们期望的事情。 ClonableIterator
创建的 Trait 对象是 Clone
和 Iterator
,对它们调用 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>())
}
有人可以解释一下或 link 相关文档,说明应用特征一揽子实施的规则与使特征本身可用的规则有何不同?
我没有对这里所有部分的参考手册的完整引用,但我看到这两种情况之间的区别是 ClonableIterator
在 [=45] 中 不可见=] mod helper
(没有use super::ClonableIterator
)。因此,在查找方法时,不会针对任意类型 查询特征,但(显然)它针对 dyn super::ClonableIterator
,大概是因为不这样做会毫无意义地无益。
所以 method lookup procedure 将大致这样做:
- 我们从
*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
类型是无条件可见的。
- 这是否有一个名为