【问题标题】:Creating a vector with non-constant length创建具有非常量长度的向量
【发布时间】:2013-05-20 16:48:54
【问题描述】:

编者注:这个问题是在 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。

【问题讨论】:

  • 这是一个很好的问题,但考虑到从 Rust 0.6 到 1.0 的所有变化,现在已经过时了......
  • 这段代码几乎无法识别为 Rust。与许多其他 1.0 之前的问题不同,这个问题现在几乎没用了。

标签: rust


【解决方案1】:

至少在 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

【讨论】:

  • with_capacity 略有不同:它只是分配了那么多的后备存储空间,而不是用元素填充向量。
【解决方案2】:

在 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 中看到这一点,其中(我假设的)是整数对的嵌套向量。

【讨论】:

    【解决方案3】:

    没有办法创建一个长度在运行时确定的恒定长度的数组;只允许使用编译时常量长度数组,因此您使用Vec&lt;i32&gt;(以前为~[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 类似)。

    【讨论】:

    • 也感谢您的语法建议:我还在为文档而苦恼!
    • 每个人都是 :) 这是目前 Rust 最大的问题之一。 (关于 Rust 问题的其他地方有 IRC 频道和 mailing list,他们几乎总是有人愿意提供帮助。)
    猜你喜欢
    • 1970-01-01
    • 2013-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多