如何创建一组未装箱的函数/闭包?

时间:2014-12-15 19:01:23

标签: arrays closures rust lifetime

  

编者注:这个问题在Rust 1.0之前被问过,并且从那时起一些语法发生了变化,但基本概念仍然存在。一些答案已针对Rust 1.0语法进行了更新。

我是Rust的新手并尝试使用JavaScript,Python等无关紧要的闭包做一些事情,但我遇到Rust的终身问题。我理解错误信息,但它让我相信我想要做的事情在Rust中很难。

我只想创建一个函数数组a,这样

  • a[0]是返回0的函数
  • a[1]是返回1
  • 的函数
  • ...
  • a[9]是返回9
  • 的函数

我试过了:

fn main() {
    let a : [||->uint,  ..10];
    for i in range(0u, 10) {
        a[i] = ||{i};
    }
    println!("{} {} {}", a[1](), a[5](), a[9]())
}

但我有一生的错误。由于需求冲突,报告的错误是“#34;无法推断出合适的生命周期”。对于a中的函数,因为生命周期不能超过while块,因此闭包不会比它们的堆栈帧寿命更长,这当然是因为我在println!中调用它们。

我确定必须有办法建立这个函数数组,但是如何?

2 个答案:

答案 0 :(得分:5)

您需要使用move || i

move表示此闭包将按值而不是引用取i。默认情况下,这些闭包只会引用i。在你的情况下,它是被禁止的,因为i的生命周期仅限于循环体。

另外,Rust会抱怨你的阵列可能没有完全初始化。为避免这种情况,您可以使用Vec<_>,也可以使用std::mem::uninitialized

fn main() {
    let mut a: [_; 10] = unsafe { std::mem::uninitialized() };
    for i in 0..10 {
        a[i] = move || i;
    }
    println!("{} {} {}", a[1](), a[5](), a[9]())
}

答案 1 :(得分:4)

可以collect从迭代器到Vec的多个闭包:

fn main() {
    let a: Vec<_> = (0..10).map(|i| move || i).collect();

    println!("{} {} {}", a[1](), a[5](), a[9]());
}

move关键字会导致i的所有权转移到关闭。

另见: