Rust:在任务中执行解除引用的闭包

时间:2014-12-05 23:16:26

标签: rust

我有一些代码,它接受一个Vector函数,然后迭代它们并在每一步执行每一个。我试图将任务合并到for循环中,以便这些函数调用可以异步执行,而不是让第一个阻塞第二个,依此类推...

let mut arr: Vec<|i32| -> i32> = Vec::new();
arr.push(function1);
arr.push(function2);

let ref num_in = os::args()[1];
let num_str = num_in.to_string();

let num = match from_str::<i32>(num_str.as_slice()) {
    Some(x) => x,
    None => panic!("Not a number"),
};

for f in arr.iter_mut() {
    spawn(proc(){
        println!("{}", (*f)(num.clone()));
    });
};

没有任务,只是在for循环中执行println!这个代码运行得很好,但是我试图通过使用任务来避免阻塞。有了这个任务,我得到了这些错误和注释......

error: the trait 'core::kinds::Send' is not implemented for the type '&mut |i32| -> i32'

note: the closure that captures 'f' requires that all captured variables implement the trait 'core::kinds::Send'

1 个答案:

答案 0 :(得分:1)

您的代码中存在一些问题:

与编译器告诉你的一样,{p> f&mut |i32|->i32。它是对其中一个向量元素的借用引用。这样的借用引用不能跨任务边界发送。这是一个简单的规则,可以防止悬空指针,从而防止内存安全错误,因为如果涉及多个线程,基于范围的生命周期保证就不会像那样工作。

但即使类型为|i32|->i32的东西目前也是借用的参考(通常),因为它借用了它的环境。如果您没有捕获任何变量(“空环境”),您可以使用fn(i32) -> i32来获取可发送的内容。您可以将其视为一个简单的函数指针。

让其他任务执行带有自己的环境的东西(如“未借用”)通常使用proc完成。这是它的目的。由于这个原因,您已经在使用proc了。编译器只是将f复制到proc中,这使得整个proc不可发送,因为借用的引用是不可发送的。

在不久的将来,我们将获得“未装箱的关闭”,这将使proc变得多余。然后,您应该可以使用Vec<Box<FnOnce(i32)->i32 + Send>>Vec<Box<Fn(i32)->i32 + Send>>代替Vec<proc(i32)->i32>。创建这些类型的框可能涉及boxmove关键字以及对特征对象的强制转换。