在Rust中向量中重复元素的最佳方法是什么?

Дми*_*бин 4 vector rust

我发现了这种方式,但对于这样一个共同的行动来说似乎过于冗长:

fn double_vec(vec: Vec<i32>) -> Vec<i32> {
    let mut vec1 = vec.clone();
    let vec2 = vec.clone();

    vec1.extend(vec2);

    vec1
}
Run Code Online (Sandbox Code Playgroud)

我知道在JavaScript中它可能只是arr2 = [...arr1, ...arr1].

Wes*_*ser 9

“将向量加倍”并不是经常做的事情,所以没有捷径可走。此外,里面的内容很重要,Vec因为这会改变可以对其执行的操作。在此特定示例中,以下代码有效:

let x = vec![1, 2, 3];

let y: Vec<_> = x.iter().cycle().take(x.len() * 2).collect();

println!("{:?}", y); //[1, 2, 3, 1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

cycle()方法要求项目中的项目Iterator实现Clonetrait,以便项目可以被复制。因此,如果您的Vec工具中的项目Clone,那么这将起作用。由于不可变引用 ( &) 实现了Clone, aVec<&Something>将起作用,但可变引用 ( &mut) 没有实现Clone,因此 aVec<&mut Something>将不起作用。

请注意,即使类型没有实现Clone,您仍然可以克隆对该类型的引用:

struct Test;

fn test_if_clone<T: Clone>(_x: T) {}

fn main() {
    let x = Test;

    test_if_clone(x); //error[E0277]: the trait bound `Test: std::clone::Clone` is not satisfied

    let y = &x;

    test_if_clone(y); //ok
}
Run Code Online (Sandbox Code Playgroud)


tur*_*too 6

基于 Wesley 的回答,您还可以使用chain将两个可迭代对象一个接一个地粘合在一起。在下面的例子中,我使用了相同Veciter()方法两次:

let x = vec![1, 2, 3];

let y: Vec<_> = x.iter().chain(x.iter()).collect();

println!("{:?}", y); //[1, 2, 3, 1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

  • 值得一提的一件事是`y`的类型是`Vec&lt;&amp;{integer}&gt;`而不是`Vec&lt;{integer&gt;`。这是一个很好的解决方案,因为它允许您处理内容无法克隆的向量。 (2认同)

blu*_*uss 5

你可以使用concat方法,这很简单:

fn double_vec(v: Vec<i32>) -> Vec<i32> {
    [&v[..], &v[..]].concat()
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,我们必须明确地制作矢量切片(这里&v[..]); 但是否则这个方法很好,因为它直接将结果分配给所需的大小然后进行复制.


Vee*_*rac 5

迭代器方法可能比memcpy向量扩展的直接方法效率低得多。

你自己的代码做的clone太多了;您可以重用按值输入:

fn double_vec(mut vec: Vec<i32>) -> Vec<i32> {
    let clone = vec.clone();
    vec.extend(clone);
    vec
}
Run Code Online (Sandbox Code Playgroud)

但是, a 的性质Vec意味着即使您设法删除了该克隆,这也可能需要一个副本,因此您通常不会比仅使用concat.

concat在切片上使用相当有效,因为它会Vec提前预分配,然后执行高效的extend_from_slice. 然而,这确实意味着将 aVec作为输入不再特别明智;写以下严格更灵活。

fn double_slice(slice: &[i32]) -> Vec<i32> {
    [slice, slice].concat()
}
Run Code Online (Sandbox Code Playgroud)