我有一个伪随机数生成器,我希望允许闭包通过可变引用来访问它。理论上,所有的生命周期应该都能够协调一致,这是它的样子:
fn someFunction<F, I>(mut crossover_point_iter_generator: F)
where F: FnMut(usize) -> I, I: Iterator<Item=usize>;
let mut rng = Isaac64Rng::from_seed(&[1, 2, 3, 4]);
someFunction(|x| (0..3).map(move |_| rng.gen::<usize>() % x));
在这里,一个闭包正在创建一个迭代器,用于包装PRNG生成的值。此迭代器包含一个map和一个闭包,该闭包具有克隆到其中的wrap范围x,但问题在于它无意中也克隆了rng,我已经验证。必须使它成为移动闭包,因为必须捕获x的值,否则闭包将超时x。
我尝试添加此行以强制将引用移动到闭包中:
let rng = &mut rng;
然而,Rust 报告了以下错误:
error: cannot move out of captured outer variable in an `FnMut` closure
我能否在move闭包内可变访问PRNG?如果不能,由于PRNG显然比函数调用生存周期更长,是否有其他解决方案(除了重新设计API)?
编辑:
我已经重写了它以删除复制问题,并且调用看起来像这样:
someFunction(|x| rng.gen_iter::<usize>().map(move |y| y % x).take(3));
这会导致一个新的错误:
error: cannot infer an appropriate lifetime for autoref due to conflicting requirements
rand
crate 有一个针对这种情况的“范围内随机数”函数。 - Shepmastergen_range
更易懂。 - Shepmaster