如何将可变引用捕获到从闭包返回的迭代器中包含的移动闭包中

瓦迪克斯

我有一个PRNG,我希望允许通过可变引用访问闭包。从理论上讲,所有内容的生命周期都应该可以计算出来,如下所示:

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生成值的迭代器。该迭代器包含一个带有闭包的映射,该闭包具有将其包装范围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
耀斑

您遇到的情况是需要多次相互冲突的可变借用,而rustc则应予以否认。我们需要了解这种情况的发生方式和原因!

注意事项将很重要:

  • Isaac64Rng实现Copy,这意味着它隐式复制而不是仅移动。我假设是遗留/向后兼容的东西。

我编写了以下版本的代码以使其变得直截了当:

extern crate rand;

use rand::Isaac64Rng;
use rand::{Rng, SeedableRng};

fn someFunction<F, I>(crossover_point_iter_generator: F)
    where F: FnMut(usize) -> I, I: Iterator<Item=usize>
{
    panic!()
}

fn main() {
    let mut rng = Isaac64Rng::from_seed(&[1, 2, 3, 4]);
    let rng = &mut rng;  /* (##) Rust does not allow. */
    someFunction(|x| {
        (0..3).map(move |_| rng.gen::<usize>() % x)
    });
}

让我指出这一点:

  • someFunction想要一个可以调用的闭包,每次调用时都返回一个迭代器。闭包是可变的,可以调用多次(FnMut)。

  • 我们必须假设所有返回的迭代器可以同时使用,而不是顺序使用(一次使用)。

  • 我们想将Rng借给迭代器,但可变借项是排他的。因此,借用规则一次不允许有多个迭代器。

  • 用FnOnce代替FnMut将是一种封闭协议的示例,可以在这里为我们提供帮助。这会让rustc看到只能有一个迭代器。

在工作版本中,没有line (##),您同时有多个活动的迭代器,那里发生了什么?这是隐式复制的开始,因此每个迭代器都将使用原始Rng的相同副本(听起来不受欢迎)。

您的第二个代码版本遇到了基本上相同的限制。

如果要解决借款的排他性问题,可以使用特殊容器,例如RefCellMutex序列化对Rng的访问。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何将捕获的变量移动到闭包内的闭包中?

来自分类Dev

如何将可变状态转换为闭包?

来自分类Dev

如何将可变状态转换为闭包?

来自分类Dev

如何从闭包返回对闭包参数的引用?

来自分类Dev

借用闭包中的可变引用来对向量进行排序

来自分类Dev

闭包是通过引用捕获的?

来自分类Dev

返回在Rust中捕获外部变量的闭包

来自分类Dev

返回可变环境的闭包

来自分类Dev

从函数内的闭包内的闭包中返回数据

来自分类Dev

如何从`FnMut`闭包中返回捕获的变量,这是同时捕获的

来自分类Dev

在Javascript闭包中捕获计数器值

来自分类Dev

事件绑定-在闭包中捕获变量

来自分类Dev

Spock 中闭包内部的参数捕获

来自分类Dev

如何将生命周期设置为在闭包中捕获的值?

来自分类Dev

闭包中变量引用的异常行为

来自分类Dev

在Swift中对闭包的引用很少

来自分类Dev

停止在闭包中通过引用传递

来自分类Dev

如何在Swift中设置对闭包/函数的弱引用?

来自分类Dev

如何在闭包中更改引用传递的数组的数据

来自分类Dev

如何将闭包中的值返回到方法中

来自分类Dev

如何在闭包中传递捕获字符串而不引起编译器错误?

来自分类Dev

如何将闭包转换为R中的字符?

来自分类Dev

从grails闭包中返回特定值

来自分类Dev

返回C ++中的闭包类型

来自分类Dev

从grails闭包中返回特定值

来自分类Dev

无法借用`Fn`闭包中的捕获外部变量为可变变量

来自分类Dev

如何在方法中调用闭包

来自分类Dev

如何理解lambda中的闭包?

来自分类Dev

如何在scala中实现闭包?