首页 > 解决方案 > 在 for 循环中引用/取消引用向量元素

问题描述

在下面的代码中,我想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);
}

据透露,我们可以将&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;
}

我的困惑(请记住,我没有涵盖模式)是我希望因为n: &i32, then&n: &&i32而不是解析为值(如果甚至可能有双重引用)。为什么会发生这种情况,其含义是否&因上下文而异?

标签: syntaxreferencerustpattern-matching

解决方案


将引用视为一种容器会有所帮助。为了比较,考虑Option,我们可以使用模式匹配“解包”值,例如在if let语句中:

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

if let Some(p) = opt {
    // do something with p
}

我们调用forSomeNone 构造函数Option,因为它们每个都产生一个类型的值Option。同样,您可以将其&视为引用的构造函数。并且语法是对称的:

let n = 100;
let reference = &n;

if let &p = reference {
    // do something with p
}

您可以在将值绑定到变量的任何地方使用此功能,这种情况无处不在。例如:

  1. if let, 如上

  2. match表达式:

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

    fn foo(&p: &i32) { ... }
    
  4. 循环:

    for &p in iter_of_i32_refs {
        ...
    }
    

而且可能更多

请注意,最后两个将不起作用,因为如果找到 a 而不是 a ,Option它们会感到恐慌,但引用不会发生这种情况,因为它们只有一个构造函数.NoneSome&

的含义是否&因上下文而异?

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


推荐阅读