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

时间:2018-09-06 11:45:17

标签: syntax reference rust pattern-matching

在下面的代码中,我想在迭代之后保留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之后,&n: &&i32而不是解析为值(如果double ref是偶数,可能)。为什么会发生这种情况?&的含义会根据上下文而有所不同?

3 个答案:

答案 0 :(得分:7)

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

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

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

我们将{{1}称为SomeNone 构造子,因为它们各自产生类型为Option的值。同样,您可以将Option视为参考的构造函数。而且语法是对称的:

&

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

  1. let n = 100; let reference = &n; if let &p = reference { // do something with p } ,如上所述

  2. if let表达式:

    match
  3. 在函数自变量中:

    match opt {
        Some(1) => { ... },
        Some(p) => { ... },
        None    => { ... },
    }
    match reference {
        &1 => { ... },
        &p => { ... },
    }
    
  4. 循环:

    fn foo(&p: &i32) { ... }
    

可能还有more

请注意,后两个不适用于for &p in iter_of_i32_refs { ... } ,因为如果找到了Option而不是None,它们会惊慌失措,但这对于引用来说是不会发生的,因为它们只有一个构造函数Some

  

&的含义是否随上下文而不同?

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

答案 1 :(得分:2)

除了其他语言(C ++)之外,&n在此情况下不是参考,而是模式匹配,这意味着它正在期待参考。
相反的是ref n,它将为您提供&&i32作为类型。

闭包也是如此,例如

(0..).filter(|&idx| idx < 10)...

请注意,这将移动变量,例如您不能使用没有实现Copy特征的类型来做到这一点。

答案 2 :(得分:2)

  

我的困惑(请记住,我没有介绍过模式)是因为我希望从n:&i32开始,然后&n:&& i32而不是将其解析为值(即使可能使用double ref)。为什么会发生这种情况,并且&的含义会根据上下文而有所不同?

当您进行模式匹配时(例如,当您编写for &n in &number_list时),并不是说n&i32,而是说&n (模式)是&i32(表达式),编译器从中推断出ni32

各种模式都会发生类似的情况,例如,if let Some (x) = Some (42) { /* … */ }中的模式匹配时,我们说Some (x)Some (42),因此x是42。 / p>