在for循环中引用/解除引用向量元素

njp*_*njp 2 syntax reference pattern-matching rust

在下面的代码,我想保留number_list,迭代之后,因为.into_iter()for默认情况下使用会消耗.因此,我假设n: &i32并且我可以n通过解除引用获得价值.

fn main() {
    let number_list = vec![24, 34, 100, 65];
    let mut largest = number_list[0];

    for n in &number_list {
        if *n > largest {
            largest = *n;
        }
    }

    println!("{}", largest);
}
Run Code Online (Sandbox Code Playgroud)

有人向我透露,我们可以将其&n用作"模式":

fn main() {
    let number_list = vec![24, 34, 100, 65];
    let mut largest = number_list[0];

    for &n in &number_list {
        if n > largest {
            largest = n;
        }
    }

    println!("{}", largest);
    number_list;
}
Run Code Online (Sandbox Code Playgroud)

我的困惑(和记住我还没有覆盖模式)是我所期望的,既然n: &i32,然后&n: &&i32而不是将其解析为值(如果使用双裁判甚至有可能).为什么会发生这种情况,并且&根据具体情况而有不同的含义?

Pet*_*all 7

它可以帮助将引用视为一种容器.为了比较,考虑一下Option,我们可以使用模式匹配来"解包"值,例如在if let语句中:

let n = 100;
let opt = Some(n);

if let Some(p) = opt {
    // do something with p
}
Run Code Online (Sandbox Code Playgroud)

我们呼吁SomeNone 构造Option,因为他们每一个生产型的值Option.以同样的方式,您可以将其&视为参考的构造函数.语法是对称的:

let n = 100;
let reference = &n;

if let &p = reference {
    // do something with p
}
Run Code Online (Sandbox Code Playgroud)

您可以在将值绑定到变量的任何位置使用此功能,该变量遍布整个地方.例如:

  1. if let, 如上

  2. match 表情:

    match opt {
        Some(1) => { ... },
        Some(p) => { ... },
        None    => { ... },
    }
    match reference {
        &1 => { ... },
        &p => { ... },
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在函数参数中:

    fn foo(&p: &i32) { ... }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 循环:

    for &p in iter_of_i32_refs {
        ...
    }
    
    Run Code Online (Sandbox Code Playgroud)

可能更多.

请注意,最后两个不起作用,Option因为如果None找到a而不是a Some,它们会发生混乱,但是引用不会发生,因为它们只有一个构造函数,&.

&根据具体情况,意义是否有所不同?

希望,如果您可以将其解释&为构造函数而不是运算符,那么您将看到它的含义不会改变.Rust的一个非常酷的功能是,您可以在表达式的右侧使用构造函数来创建值,并在左侧使用它们将它们分开(解构).