首页 文章

创建具有非恒定长度的向量

提问于
浏览
13

编者注:在Rust 1.0之前问过这个问题,问题中的一些断言在Rust 1.0中不一定正确 . 一些答案已更新,以解决这两个版本 .

我想创建一个向量,但我只知道我希望向量在运行时的大小 . 这就是我现在正在做的事情(即创建一个空的,可变的向量,并向其添加向量):

fn add_pairs(pairs: ~[int]) -> ~[int] {
    let mut result : ~[int] = ~[];
    let mut i = 0;
    while i < pairs.len() {
        result += ~[pairs[i] + pairs[i + 1]];
        i += 2;
    }
    return result;
}

这就是我想要的方式(即创建一个向量并将所有内容放入其中,而不是一起添加大量向量):

fn add_pairs(pairs: ~[int]) -> ~[int] {
    let number_of_pairs = pairs.len() / 2;
    let result : ~[int, ..number_of_pairs];
    let mut i = 0;
    while i < pairs.len() {
        result[i] = pairs[2 * i] + pairs[2 * i + 1];
        i += 1;
    }
    return result;
}

不幸的是,做到这一点给了我类似的东西:

error: expected constant expr for vector length: Non-constant path in constant expr
let result: ~[int, ..number_of_pairs];
             ^~~~~~~~~~~~~~~~~~~~~~~~

我得到的印象是向量必须在编译时知道它们的大小(因此你需要将它们的大小设置为常量) . 来自Java背景,我很困惑!有没有办法创建一个只在运行时知道它的大小的向量?

我正在使用Rust 0.6 .

3 回答

  • 11

    没有办法创建一个常量长度的数组,其长度在运行时确定;只允许编译时常量长度数组,所以(第一种方法)(变体) Vec<i32> (以前为 ~[int] )是唯一受支持的方式 . 您可以使用vec![0; number_of_pairs]创建正确大小的向量并使用第二部分 .


    你正在尝试做什么有很多辅助函数(使用 while 直接Rust应该非常罕见):

    fn add_pairs(pairs: &[i32]) -> Vec<i32> {
        let mut result = Vec::new();
        for i in 0..(pairs.len() / 2) {
            result.push(pairs[2 * i] + pairs[2 * i + 1])
        }
        result
    }
    

    甚至

    fn add_pairs(pairs: &[i32]) -> Vec<i32> {
        pairs
            .chunks(2)
            .filter(|x| x.len() == 2)
            .map(|x| x[0] + x[1])
            .collect()
    }
    

    文件:chunksfiltermapcollect . ( filter 只是因为 chunks 的最后一个元素可能有长度为1.)

    另请注意,添加两个向量会分配一个全新的向量,而 push 不会这样做并且速度更快(并且 .collect 类似) .

  • 14

    在Rust版本1.0.0中,他们使 std::vec:Vec 公共结构稳定,以便您可以使用 let mut my_vec = Vec::new(); 实例化可增长的向量 . 您也可以像这样使用 vec! 宏: let mut another_vec = vec![1isize, 2isize, 3isize]; 重要的是要注意的是,在这两种情况下变量都是你的'重新分配必须是可变的 .

    使用这些向量,您可以为单个项目调用 my_vec.push(num); ,或者 another_vec.extend_from_slice(["list", "of", "objects"]); 将项目添加到向量的末尾 .

    对于您的具体问题,您可以执行以下操作:

    fn add_pairs(pairs: Vec<(Vec<isize>)>) -> Vec<isize> {
        let mut result = Vec::new();
        for pair in pairs.iter() {
            result.push(pair[0]);
            result.push(pair[1]);
        }
        return result;
    }
    

    你可以在行动中看到这个on the Rust Playground你所拥有的(我假设的)是整数对的嵌套向量 .

  • 2

    至少在Rust 1.0中,有一个Vec::with_capacity()函数可以处理这种情况 .

    示例代码:

    let n = 44; // pretend this is determined at run time
    let mut v = Vec::<f64>::with_capacity(n);
    v.push(6.26);
    println!("{:?}", v);            // prints [6.26]
    println!("{:?}", v.len());      // prints 1
    println!("{:?}", v.capacity()); // prints 44
    

相关问题