我发现了这种方式,但对于这样一个共同的行动来说似乎过于冗长:
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].
“将向量加倍”并不是经常做的事情,所以没有捷径可走。此外,里面的内容很重要,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)
基于 Wesley 的回答,您还可以使用chain将两个可迭代对象一个接一个地粘合在一起。在下面的例子中,我使用了相同Vec的iter()方法两次:
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)
你可以使用concat方法,这很简单:
fn double_vec(v: Vec<i32>) -> Vec<i32> {
[&v[..], &v[..]].concat()
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我们必须明确地制作矢量切片(这里&v[..]); 但是否则这个方法很好,因为它直接将结果分配给所需的大小然后进行复制.
迭代器方法可能比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)
| 归档时间: |
|
| 查看次数: |
912 次 |
| 最近记录: |