如何用值从 0 到 n 初始化一个向量?

16

在Rust中,如何从0n初始化向量?是否有其他方法可以做到这一点,而不是创建一个空向量并在循环内调用push?

我更喜欢一行代码实现。

2个回答

19

一个区间可以被收集成为一个向量:

pub fn sequence(n: u32) -> Vec<u32> {
    (0..n).collect()
}

游乐场


8
更好的写法(在我看来):Vec::from_iter(0..n) - Chayim Friedman
这两个解决方案都很好,而且可以帮我省下三行代码 :) 我需要再考虑一下哪一个更好... - Thorkil Værge
2
我认为你会更经常地看到collect()被使用,而不是from_iter(),因为它可以直接附加在现有的迭代器链上,但从功能上讲,它们做的事情是一样的。 - kmdreko
1
@kmdreko 实际上有一个区别:collect() 需要一个 Iterator,而 FromIterator::from_iter() 接受一个 IntoIterator。范围是 Iterator,因此没有关系,但对于数组来说,例如 [1, 2, 3].into_iter().collect::<Vec<_>>()Vec::from_iter([1, 2, 3]) 是一个更大的区别。 - Chayim Friedman
5
自从 2021 版本开始,由于 FromIterator 已经在预导中,因此我期望会有更多人使用它(我现在也更加频繁地使用它,并且我也看到其他人的代码中也在使用)。当你不需要对可迭代对象进行任何转换,只需将其转换为另一个容器时,使用 Container::from_iter(v) 比使用 v.into_iter().collect::<Container>() 更加简洁。 - Chayim Friedman

5

以下是一行代码实现的方法:

let n = 4;

let v: Vec<i32> = (0..n).collect();  // the last element will be n-1
assert_eq!(v, vec![0, 1, 2, 3]);

let v: Vec<i32> = (0..=n).collect();  // the last element will be n
assert_eq!(v, vec![0, 1, 2, 3, 4]);

或者,另外一个选择是:
let v: Vec<i32> = Vec::from_iter(0..n);  // the last element will be n-1
assert_eq!(v, vec![0, 1, 2, 3]);

let v: Vec<i32> = Vec::from_iter(0..=n);  // the last element will be n
assert_eq!(v, vec![0, 1, 2, 3, 4]);

除了 i32 以外,我们可以使用其他数字类型,比如 u8u16i8等。这是因为 collect()Vec::from_iter 方法都是泛型方法。

所有这些解决方案都利用了 RangeRangeInclusive 结构体,两者都实现了 Iterator 接口。这使它们很容易转换为一个 Vec,通常是通过 collect() 方法完成的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接