一个简单的测试用例,由于堆栈溢出而失败:
// trait to say FnMut has a clone_box method
pub trait ClonableFnMut<A>: FnMut(A) {
fn clone_box(&self) -> Box<dyn ClonableFnMut<A> + Send + 'static>;
}
// overridden .clone() for Box<ClonableFnMut> that calls .clone_box on f
impl<A: 'static> Clone for Box<dyn ClonableFnMut<A> + Send + 'static> {
fn clone(&self) -> Self {
self.clone_box()
}
}
// .clone_box() on FnMut clones itself and wraps itself in a new Box
impl<A, F: FnMut(A) + Clone + Send + 'static> ClonableFnMut<A> for F {
fn clone_box(&self) -> Box<dyn ClonableFnMut<A> + Send + 'static> {
Box::new(self.clone())
}
}
fn main() {
let mut f: Box<dyn ClonableFnMut<u8> + Send + 'static> = Box::new(|_x|{});
println!("{:?}", f(3));
println!("{:?}", f.clone()(4));
}
理论上:
.clone()
上的Box<ClonableFnMut>
。.clone_box()
上调用FnMut
。FnMut
现在可以自己调用.clone()
,因为它已标记为克隆。.clone_box()
在新Box中返回此克隆的FnMut
(自身)但实际上:
.clone()
上手动呼叫Box<ClonableFnMut>
。.clone_box()
上调用Box<FnMut>
。self.clone()
似乎是self = box
。Box<FnMut>
clone()
,从步骤1开始。第4步发生的真正原因是什么?
答案 0 :(得分:3)
实际上发生的事情略有不同:
clone
上致电Box
... clone_box
的{{1}} ... Box
上的clone
,结束循环。发生这种情况是因为您对Box
的实现只调用了Clone
,但是self.clone_box()
是具有clone_box
特性的一种方法。由于全面实施,ClonableFnMut
尤其是在Box<dyn ClonableFnMut<A> + Send + 'static>
上实现了此特征,Box本身满足了F: FnMut(A) + Clone + Send + 'static
的要求。
为避免这种情况,您需要强制Clone
实现为clone_box
的内容而不是Box
本身的内容调用Box
方法。有两种明显不同的样式方式: