如何在不获取切片的情况下对向量进行解构?

问题描述 投票:4回答:2

我可以通过获取一个向量的切片并引用该元组中的项来破坏一个元组的向量:

let items = vec![("Peter".to_string(), 180)];

if let [(ref name, ref age)] = items.as_slice() {
    println!("{} scored {}", name, age);
};

如何直接对向量进行解构,将项目移出元组。像这样的东西:

let items = vec![("Peter".to_string(), 180)];

if let [(name, age)] = items {
    println!("{} scored {}", name, age);
};

编译以上内容会导致错误:

error[E0529]: expected an array or slice, found `std::vec::Vec<(std::string::String, {integer})>`
 --> src/main.rs:4:12
  |
4 |     if let [(name, age)] = items {
  |            ^^^^^^^^^^^^^ pattern cannot match with input type `std::vec::Vec<(std::string::String, {integer})>`
vector rust pattern-matching slice destructuring
2个回答
3
投票

您一次要问两个不相交的问题:

  1. 如何移出向量?
  2. 如何解构物品?

第二个很简单:

let item = ("Peter".to_string(), 180);
let (name, score) = item;

您不需要if let语法,因为这种模式匹配无法失败。当然,在销毁item后,您将无法使用它,因为您已将[[所有权转让从item转移到namescore

第一个问题更难,并且成为Rust的核心部分。如果您将所有权移出矢量,那么

矢量处于什么状态

?在C语言中,向量中会有一些未定义的内存,等待将程序散开。假设您在该字符串上调用了free,然后在向量中使用指向同一字符串的东西时会发生什么?有几种解决方法...

引导程序继续拥有项目

let items = vec![("Peter".to_string(), 180)]; if let Some((name, score)) = items.first() { println!("{} scored {}", name, score); }
在这里,我们抓取第一个项目的[[a reference to]],然后引用名称和分数。由于向量可能没有任何项目,因此它返回Option,因此我们确实使用if let。编译器不允许我们使用这些项的时间超过向量的生存期。

从向量转移一个元素的所有权

let mut items = vec![("Peter".to_string(), 180)]; let (name, score) = items.remove(0); // Potential panic! println!("{} scored {}", name, score);

[这里,我们remove来自数组的第一项。向量不再拥有它,我们可以用它做任何想做的事情。我们立即对其进行销毁。 itemsnamescore都具有独立的生存期。
从向量转移所有元素所有权

let items = vec![("Peter".to_string(), 180)]; for (name, score) in items { println!("{} scored {}", name, score); }

这里,我们
消费
向量,因此在for循环后不再可用。 namescore的所有权转移到循环绑定中的变量中。

克隆项目

let items = vec![("Peter".to_string(), 180)]; let (name, score) = items[0].clone(); // Potential panic! println!("{} scored {}", name, score);

这里,我们在向量中创建
new
个项目的版本。我们拥有新商品,而矢量拥有原始商品。


1
投票
© www.soinside.com 2019 - 2024. All rights reserved.