Pet*_*rne 9 vector pattern-matching destructuring slice rust
我可以通过获取向量的切片和对元组中项目的引用来解构元组向量:
let items = vec![("Peter".to_string(), 180)];
if let [(ref name, ref age)] = items.as_slice() {
println!("{} scored {}", name, age);
};
Run Code Online (Sandbox Code Playgroud)
如何直接解构向量,将项目移出元组。像这样的东西:
let items = vec![("Peter".to_string(), 180)];
if let [(name, age)] = items {
println!("{} scored {}", name, age);
};
Run Code Online (Sandbox Code Playgroud)
编译上述结果导致错误:
let items = vec![("Peter".to_string(), 180)];
if let [(ref name, ref age)] = items.as_slice() {
println!("{} scored {}", name, age);
};
Run Code Online (Sandbox Code Playgroud)
你同时问两个不相交的问题:
第二个很简单:
let item = ("Peter".to_string(), 180);
let (name, score) = item;
Run Code Online (Sandbox Code Playgroud)
您不需要if let
语法,因为这种模式匹配不会失败。当然,item
解构后不能使用,因为你已经将所有权从item
toname
和转移了score
。
第一个问题比较难,并且涉及到 Rust 的核心部分。如果您将所有权从向量中转移出来,那么向量处于什么状态?在 C 中,您将有一些未定义的内存块位于向量中,等待分解您的程序。假设你调用free
了那个字符串,那么当你在向量中使用指向同一个字符串的东西时会发生什么?
有几种方法可以解决它...
let items = vec![("Peter".to_string(), 180)];
if let Some((name, score)) = items.first() {
println!("{} scored {}", name, score);
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们抓住一个参考的第一个项目,然后引用的名称和得分。由于向量可能没有任何项目,它返回一个Option
,所以我们确实使用if let
。编译器不会让我们在向量生命周期内使用这些项目。
let mut items = vec![("Peter".to_string(), 180)];
let (name, score) = items.remove(0); // Potential panic!
println!("{} scored {}", name, score);
Run Code Online (Sandbox Code Playgroud)
在这里,我们remove
是数组中的第一项。vector 不再拥有它,我们可以用它做任何我们想做的事情。我们立即对其进行解构。items
,name
并且score
都有独立的生命周期。
let items = vec![("Peter".to_string(), 180)];
for (name, score) in items {
println!("{} scored {}", name, score);
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们消耗了向量,因此它在for
循环后不再可用。的所有权name
和score
在环路中结合被转移到的变量。
let items = vec![("Peter".to_string(), 180)];
let (name, score) = items[0].clone(); // Potential panic!
println!("{} scored {}", name, score);
Run Code Online (Sandbox Code Playgroud)
在这里,我们制作了向量中项目的新版本。我们拥有新项目,向量拥有原始项目。