如何在不切片的情况下对向量进行解构? [英] How do I destructure a vector without taking a slice?

查看:68
本文介绍了如何在不切片的情况下对向量进行解构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I can destructure a vector of tuples by taking a slice of a vector and references to the items within the tuple:

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

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

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

How can I destructure the vector directly, moving the items out of the tuple. Something like this:

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

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

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

Compiling the above results in the error:

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

推荐答案

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

You are asking two disjoint questions at once:

  1. 如何移出向量?
  2. 我如何破坏物品?

第二个很简单:

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

您不需要 if let 语法,因为这种模式匹配无法失败.当然,解构后不能使用 item ,因为您已经将所有权从 item 转移到了 name 得分.

You don't need the if let syntax because there no way for this pattern-matching to fail. Of course, you can't use item after destructuring it because you've transferred ownership from item to name and score.

第一个问题更难,并且成为Rust的核心部分.如果您将所有权从矢量中移出,那么矢量处于什么状态?在C语言中,向量中会有一些未定义的内存,等待将程序散开.假设您在该字符串上调用了 free ,那么当您使用指向相同字符串的向量中的东西时会发生什么?

The first question is harder, and gets to a core part of Rust. If you transfer ownership out of a vector, then what state is the vector in? In C, you would have some undefined chunk of memory sitting in the vector, waiting to blow apart your program. Say you called free on that string, then what happens when you use the thing in the vector that pointed to the same string?

有几种解决方法...

There are a few ways to solve it...

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

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

在这里,我们获取对第一项的引用 ,然后引用名称和分数.由于向量可能没有任何项目,因此它返回一个 Option ,因此我们使用 if let .编译器将不允许我们使用这些项的时间超过向量的生存期.

Here, we grab a reference to the first item and then references to the name and score. Since the vector may not have any items, it returns an Option, so we do use if let. The compiler will not let us use these items any longer than the vector lives.

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

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

在这里,我们删除数组中的第一项.向量不再拥有它,我们可以用它做任何想做的事情.我们立即对其进行销毁. items name score 将具有独立的生存期.

Here, we remove the first item from the array. The vector no longer owns it, and we can do whatever we want with it. We destructure it immediately. items, name and score will all have independent lifetimes.

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

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

在这里,我们消耗向量,因此在 for 循环之后,该向量将不再可用.名称 name score 的所有权转移到循环绑定中的变量中.

Here, we consume the vector, so it is no longer available to use after the for loop. Ownership of name and score is transferred to the variables in the loop binding.

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

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

在这里,我们对向量中的项目进行 new 个版本.我们拥有新项目,向量拥有原始项目.

Here, we make new versions of the items in the vector. We own the new items, and the vector owns the original ones.

这篇关于如何在不切片的情况下对向量进行解构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆