要创建一个包含其他向量内容的新向量,我现在正在这样做:
fn func(a: &Vec<i32>, b: &Vec<i32>, c: &Vec<i32>) {
let abc = Vec<i32> = {
let mut tmp = Vec::with_capacity(a.len(), b.len(), c.len());
tmp.extend(a);
tmp.extend(b);
tmp.extend(c);
tmp
};
// ...
}
有没有更直接/更优雅的方式来做到这一点?
答案 0 :(得分:4)
可以使用concat
方法,但是值必须是切片,或者可以借给切片,而不是问题中给出的&Vec<_>
。
一个例子,类似于问题:
fn func(a: &Vec<i32>, b: &Vec<i32>, c: &Vec<i32>) {
let abc = Vec<i32> = [a.as_slice(), b.as_slice(), c.as_slice()].concat();
// ...
}
但是,正如@mindTree所指出的那样,使用&[i32]
类型参数更加惯用,并且无需转换。例如:
fn func(a: &[i32], b: &[i32], c: &[i32]) {
let abc = Vec<i32> = [a, b, c].concat();
// ...
}
SliceConcatExt::concat
是函数的更通用版本,可以将多个切片连接到Vec。它将每个切片的大小相加以预先分配正确容量的Vec,然后重复扩展。
fn concat(&self) -> Vec<T> {
let size = self.iter().fold(0, |acc, v| acc + v.borrow().len());
let mut result = Vec::with_capacity(size);
for v in self {
result.extend_from_slice(v.borrow())
}
result
}
答案 1 :(得分:2)
One possible solution might be to use the Chain
iterator:
let abc: Vec<_> = a.iter().chain(b).chain(c).collect();
However, in your example you are borrowing the slices, so we'll need to either deref each borrowed element or use the Cloned
iterator to copy each integer. Cloned
is probably a bit easier and as efficient as we are working with small Copy
data (i32
):
let abc: Vec<_> = a.iter().cloned()
.chain(b.iter().cloned())
.chain(c.iter().cloned())
.collect();
Seeing as each of these iterators are ExactSizeIterator
s, it should be possible to allocate the exact size for the target Vec
up front, however I'm unware whether or not this is actually the case in the std implementation (they might be waiting on specialization to land before adding this optimisation).