12

我可以通过获取向量切片并引用元组中的项目来解构元组向量:

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})>`
4

2 回答 2

7

你同时问两个不相交的问题:

  1. 我怎样才能移出向量?
  2. 如何解构项目?

第二个很简单:

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

您不需要if let语法,因为这种模式匹配不可能失败。当然,解构后就不能使用item了,因为你已经把所有权从转移itemnamescore

第一个问题更难,涉及到 Rust 的核心部分。如果您将所有权转移出向量,那么向量处于什么状态?在 C 语言中,您将有一些未定义的内存块位于向量中,等待破坏您的程序。假设你调用free了那个字符串,那么当你使用向量中指向同一个字符串的东西时会发生什么?

有几种方法可以解决它...

向量继续拥有这些项目

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

if let Some((name, score)) = items.first() {
    println!("{} scored {}", name, score);
}

在这里,我们获取对第一项的引用,然后引用名称和分数。由于向量可能没有任何项目,它返回一个Option,所以我们使用if let。编译器不会让我们使用这些项目的时间超过向量的生命周期。

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

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

let (name, score) = items.remove(0); // Potential panic!
println!("{} scored {}", name, score);

在这里,我们remove是数组中的第一项。vector 不再拥有它,我们可以用它做任何我们想做的事情。我们立即对其进行解构。items,name并且score都有独立的生命周期。

从向量转移所有元素所有权

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

for (name, score) in items {
    println!("{} scored {}", name, score);
}

在这里,我们使用for了向量,因此在循环之后不再可以使用它。name和的所有权score转移到循环绑定中的变量。

克隆项目

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

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

在这里,我们制作了向量中项目的版本。我们拥有新项目,向量拥有原始项目。

于 2015-03-28T14:50:26.067 回答
2

你不能这样做,Vec 在 std 中的定义

pub struct Vec<T> {
    ptr: Unique<T>,
    len: usize,
    cap: usize,
}

所以你不能直接匹配它,只有:

match xs {
    Vec { ptr: x, .. } => {...}
} 

error: field `ptr` of struct `collections::vec::Vec` is private
于 2015-03-28T11:39:03.260 回答