为特定大小创建零向量


76

我想使用在运行时确定的特定大小初始化零向量。

在C中,它将像:

int main(void)
{
    uint size = get_uchar();
    int A[size][size];
    memset(A, 0, size*size*sizeof(int));
}

这是我尝试在Rust中编写的辅助函数,但我认为切片语法0..size会冒犯编译器。此外,它看起来比C版本更冗长。有没有更惯用的方法来做到这一点?

fn zeros(size: u32) -> Vec<i32> {
    let mut zero_vec: Vec<i32> = Vec::with_capacity(size);
    for i in 0..size {
        zero_vec.push(0);
    }
    return zero_vec;
}

我发誓以前的文档曾经在这里解释一种from_elem()方法,但这种表示法的排列似乎都不起作用[0 ; size]

我想最终将其粘贴到子字符串搜索算法中:

pub fn kmp(text: &str, pattern: &str) -> i64 {
    let mut shifts = zeros(pattern.len()+1);
}

Answers:


89

要初始化给定长度的零(或任何其他常数值)的矢量,可以使用vec!宏:

let len = 10;
let zero_vec = vec![0; len];

就是说,您的函数在修复了几个语法后就为我工作了:

fn zeros(size: u32) -> Vec<i32> {
    let mut zero_vec: Vec<i32> = Vec::with_capacity(size as usize);
    for i in 0..size {
        zero_vec.push(0);
    }
    return zero_vec;
}

uint在Rust 1.0中不再存在,size需要将其强制转换为usize,并且需要匹配的向量的类型(已更改let mut zero_vec: Vec<i64>let mut zero_vec: Vec<i32>


4
我将Rust更新为1.0,let mut shifts = vec![0; pattern.len()];现在可以直接使用...糟糕。在此之前,我有一个error: expected , found .`。/ search.rs:17 zero_vec.push(0);`没有任何意义。
elleciel 2015年

3
我自己去过那里。当我刚开始时,很难知道我是否使用了不正确的语法,或者自上次更新以来或自阅读文档以来,语法是否刚刚发生了变化。我真的很高兴我们现在有了Beta,并为1.0感到兴奋。顺便说一句,您正在使用rustup.sh来更新Rust?如果是这样,您可能想要获取脚本的最新版本,该脚本将立即获取Beta版,而不是夜间发布。
anderspitman 2015年

2
但这就是为什么我最喜欢这种语言的原因-社区的支持很棒,对我的菜鸟问题不投反对票。:)是的,我卷曲了最新的rustup.sh。非常感谢!现在我只需要弄清楚对字符串元素的索引访问...
elleciel 2015年

当然,您可能会问自己,为什么首先要针对如此基本的问题查找答案。这在大多数其他语言中更为直观,例如,在初始化数组/向量时默认为零的语言。
Maarten Bodewes,

一个非常菜鸟的问题,但是当我这样做时,我最终得到一个2元素向量0和3,其中我试图将其初始化为3的大小。是否存在一些会导致初始化行为不同的条件?
特德福德

14

这是另一种方式,更短。它适用于Rust 1.0:

fn zeros(size: u32) -> Vec<i32> {
    vec![0; size as usize]
}

fn main() {
    let vec = zeros(10);
    for i in vec.iter() {
        println!("{}", i)
    }
}

3
这与@anders答案的最后部分有何不同?
Shepmaster 2015年

10

您还可以使用该iter::repeat函数,我认为它是“更惯用的”(对我来说看起来更好):

use std::iter;

fn zeros(size: usize) -> Vec<i32> {
    iter::repeat(0).take(size).collect()
}

是否认为这比使用vec更惯用!直?那会更快吗?
anderspitman 2015年

@anders不知道;我同意该vec!版本看起来也不错。我想尝试一些基准测试并没有什么坏处,当我回到家时可以这样做。
tckmn 2015年

是的,您现在让我想知道vec的实现方式!是。我看看是否可以抽出一些时间对此进行深入研究。
anderspitman 2015年

8
使用vec宏被认为是惯用的,之所以添加该宏是因为人们不想这样做。
史蒂夫·克拉伯尼克

1
注:::<Vec<i32>>是多余的,类型推断可以自动算出它,因为它已经是表达的类型,所以你可以只使用.collect()在这里。
Matthieu M.

3

您可以使用调整大小

let mut v = Vec::new();
let l = 42;
v.resize(l, 0u32);

5
vec!使用0进行分配时更有效,因为它使用RawVec::with_capacity_zeroed(),而使用更复杂的值生成器的.resize()调用.extend_with()。对于其他值,两者都使用,.extend_with()因此收益大致相同。
Jocelyn
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.