我有不可变的向量a
和b
,其中的元素复制起来很便宜,我想创建一个向量,它形成了这些现有向量的连接,而不改变它们(*)。
An earlier question addressed it if one of the vectors is mutable,所以一个明显的答案是首先克隆载体a
,例如
let mut r = a.clone();
r.extend(&b);
字符串
但这似乎既不优雅也不高效(扩展很容易导致一次不必要的重新分配,对吧?)。(corrected) best alternative I (being a Rust noob) come up with为:
fn cat(a: &Vec<i32>, b: &Vec<i32>) -> Vec<i32> {
let mut r = Vec::<i32>::with_capacity(a.len() + b.len());
r.extend(a);
r.extend(b);
r
}
型
由于这些元素的复制成本很低,所以more generic question for vectors of strings的答案应该适用于这里,但是vec![a, b].concat()
似乎只有在通过将向量移动到其中来构造向量的向量时才有效,因为vec![&a, &b].concat()
产生“未找到名为concat
的方法”。
对于这个看似简单的工作,是否有一个一行程序,即使它不是最佳的?
- (*)原来“不变”有两个意思:
- 只是不可变的,在Rust中这意味着如果代码编译,它不会看到值改变的变量;但是变量的值可能会被移出,并且将来的代码不能再使用该变量。
- 实际上是只读的,使变量保持不变,以供将来的代码使用;这就是我要找的东西。
3条答案
按热度按时间dfddblmv1#
concat
可以正常工作,如果使用正确:字符串
bprjcwpo2#
数组可以将
concat()
切片为一个向量,你只需要给予编译器一个更强的提示:字符串
这里有一个rust playground to try it out。可以看到
a
和b
都没有被消耗,combined
是一个新的向量。请注意,如果您尝试使用&
简写借用,而不是指定as_slice()
,则此操作将失败。zdwk9cvp3#
编者按:在提供了这个答案后,OP改变了他们的问题。请参考创建此答案的version of the question。
你的第一个例子并没有真正意义。您提到了不变性,但是由于您将向量的所有权转移到
cat
函数,因此它可以选择变量的可变性。在这种情况下,您也可以重用其中一个的分配:字符串
扩展很容易导致不必要的重新分配
这在技术上是可能的,但极不可能。迭代器具有
size_hint
方法是有原因的--这允许集合在任何可能的情况下精确分配。一句俏皮话
型
这破坏了向量
a
和b
的分配(而不是它们内部的元素),并创建了一个新的分配来保存所有项。如果你有不可变的 * slice *,你可以使用同样的技术:
型
参见: