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);