首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何将不可变向量串联在一行中?

如何将不可变向量串联在一行中?
EN

Stack Overflow用户
提问于 2018-11-25 08:02:02
回答 3查看 5.4K关注 0票数 7

我有不变的向量ab,在这些向量中,元素的复制成本很低,我希望创建一个向量,在不改变它们的情况下形成这些现有向量的级联。

前面的一个问题是,如果其中一个向量是可变的,它就会解决这个问题。,所以一个明显的答案是首先克隆载体a

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let mut r = a.clone();
r.extend(&b);

但这似乎既不优雅,也不有效(扩展很容易导致不必要的重新分配,对吗?)(更正)最好的备选方案I(作为一个锈菌)想出是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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
}

由于元素的复制成本很低,所以字符串向量的更一般的问题的答案应该适用于这里,但是vec![a, b].concat()似乎只有在通过将向量移动到向量来构造向量时才能工作,因为vec![&a, &b].concat()生成“没有找到名为concat的方法”。

这个看似简单的工作,即使不是最理想的,也有一条线吗?

(*)“不改变”有两个含义:

  • 只是不可变,在Rust中,这意味着如果代码编译,它将不会看到变量具有更改的值;但是变量可能被移出,而且以后的代码将不再使用它。
  • 实际上是只读的,将变量保留为进一步的或未来的代码。
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-11-25 23:50:36

如果正确使用,concat确实可以工作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
fn cat(a: &[i32], b: &[i32]) -> Vec<i32> {
    [a, b].concat()
}

fn main() {
    let a = vec![1, 2, 3];
    let b = vec![7, 8, 9];
    println!("{:?}", cat(&a, &b));
}
票数 8
EN

Stack Overflow用户

发布于 2021-10-14 16:10:30

数组可以concat()切片到一个向量,您只需要给编译器一个更强的提示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let combined = [a.as_slice(), b.as_slice()].concat();

这是一个生锈操场试一试。您可以看到,ab都没有被消耗,而combined是一个新的向量。请注意,如果您尝试使用&的缩写来表示借款,而不是指定as_slice(),这就失败了。

票数 3
EN

Stack Overflow用户

发布于 2018-11-25 08:08:09

编者按:在提供了这个答案之后,OP改变了他们的问题。请参考这个答案是从问题的版本创建的。

你的第一个例子并没有什么意义。您提到了不可变性,但是由于要将向量的所有权传递给cat函数,所以它可以选择变量的可变性。在这种情况下,您最好重用其中之一的分配:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
fn cat(mut a: Vec<i32>, b: Vec<i32>) -> Vec<i32> {
    a.extend(b);
    a
}

扩展很容易导致不必要的重新分配。

这在技术上是可能的,但极不可能实现。迭代器拥有size_hint方法是有原因的--这允许集合尽可能精确地分配。

一条龙

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
a.into_iter().chain(b).collect::<Vec<_>>()

这破坏了向量ab (而不是它们中的元素)的分配,并创建了一个新的分配来保存所有的项。

如果您有不可变的切片,则可以使用相同的技术:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
fn cat<T: Clone>(a: &[T], b: &[T]) -> Vec<T> {
    a.iter().chain(b).cloned().collect()
}

另请参阅:

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53469274

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文