Vector 如何在不切片的情况下分解向量?
我可以通过获取向量切片和对元组中项目的引用来分解元组向量:Vector 如何在不切片的情况下分解向量?,vector,rust,pattern-matching,slice,destructuring,Vector,Rust,Pattern Matching,Slice,Destructuring,我可以通过获取向量切片和对元组中项目的引用来分解元组向量: 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
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);
};
在错误中编译上述结果:
错误[E0529]:应为数组或片,找到'std::vec::vec'`
-->src/main.rs:4:12
|
4 |如果出租[(姓名、年龄)]=项目{
|^^^^^^^^^^^^^^^^模式无法与输入类型“std::vec::vec”匹配`
你不能这么做,是吗
但是
您同时提出两个不相交的问题:
我怎样才能从向量中移出
如何分解项目
第二点很简单:
let item = ("Peter".to_string(), 180);
let (name, score) = item;
您不需要使用if let
语法,因为此模式匹配不会失败。当然,在对其进行分解后,您不能使用项目
,因为您已将所有权从项目
转移到名称
和分数
第一个问题更难,并且涉及到Rust的核心部分。如果你将所有权从向量转移出去,那么向量处于什么状态?在C中,向量中会有一些未定义的内存块,等待着拆开你的程序。假设你在该字符串上调用了free
,那么当你在指向同一字符串的向量
有几种方法可以解决这个问题
向量继续拥有这些项
在这里,我们获取对第一项的引用,然后引用名称和分数。由于向量可能没有任何项,因此它返回一个选项
,因此我们使用if let
。编译器不允许我们在向量的生命周期内使用这些项
从向量中转移一个元素的所有权
在这里,我们从数组中删除第一项。向量不再拥有它,我们可以用它做任何我们想做的事情。我们立即对它进行分解。项
,名称
和分数
都有独立的生存期
从向量中转移所有元素的所有权
在这里,我们使用向量,因此它在for
循环之后不再可用。name
和score
的所有权转移到循环绑定中的变量
克隆项目
在这里,我们为向量中的项创建新版本。我们拥有新项,向量拥有原始项。相关问题:即使可以,您可能也不应该也不想直接干扰指针。当然,只需演示如何匹配向量谢谢!很遗憾,将项从向量中移出无法获得支持编译器以解构项
元组时相同的方式转移所有权。@PeterHorne我不知道你的意思。如果foo=vec[0]
将所有权从向量转移到变量foo
,你想要什么vec[0]
是指所有权转移之后?与在(a,b)=项目之后尝试访问项目时相同(使用部分移动的值)@彼得霍恩:不过,你高估了当前的锈迹类型系统。部分移动仅适用于未实施下降
特征的结构(请参见=>无法移出定义下降
特征的类型人员
),因为编译器无法知道Drop
特性将依赖于什么。
match xs {
Vec { ptr: x, .. } => {...}
}
error: field `ptr` of struct `collections::vec::Vec` is private
let item = ("Peter".to_string(), 180);
let (name, score) = item;
let items = vec![("Peter".to_string(), 180)];
if let Some((name, score)) = items.first() {
println!("{} scored {}", name, score);
}
let mut items = vec![("Peter".to_string(), 180)];
let (name, score) = items.remove(0); // Potential panic!
println!("{} scored {}", name, score);
let items = vec![("Peter".to_string(), 180)];
for (name, score) in items {
println!("{} scored {}", name, score);
}
let items = vec![("Peter".to_string(), 180)];
let (name, score) = items[0].clone(); // Potential panic!
println!("{} scored {}", name, score);