我有一个通过回调生成数据的结构体。在回调中,我需要修改结构体,处理,然后取消修改。在回调结束时,结构体在语义上没有修改,但代码有一个递归的可变借用,这是Rust不喜欢的。
下面是一个简化的example:
struct A(u64);
impl A {
fn change(&mut self, x: u64) { self.0 ^= x; }
fn gen_data(&self, mut cb: impl FnMut(u64)) {
for i in 0..64 { cb(self.0 >> i) }
}
}
fn compute(a: &mut A) -> u64 {
let mut acc = 0;
a.gen_data(|x| {
a.change(x); // change
acc ^= a.0; // accumulate result
a.change(x); // undo
});
acc
}
字符串
我不能把gen_data
变成迭代器,因为在实际实现中有很多条件。我不想克隆a
,因为它是一个很大的数据结构,也不想把回调数据积累在一个容器中,然后处理,因为这是热代码。
有没有办法重新构造这段代码,让Rust相信它可以工作?
1条答案
按热度按时间9gm1akwq1#
你可以让
gen_data
使用&mut self
,并向FnMut
添加一个&mut Self
参数,然后通过该参数而不是通过a
进行更改:字符串