我有一些代码,它接受一个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'
答案 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>
。创建这些类型的框可能涉及box
和move
关键字以及对特征对象的强制转换。