在下面的代码中,我想在迭代之后保留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是偶数,可能)。为什么会发生这种情况?&
的含义会根据上下文而有所不同?
答案 0 :(得分:7)
将引用视为一种容器可以有所帮助。为了进行比较,请考虑Option
,在这里我们可以使用模式匹配来“解包”值,例如在if let
语句中:
let n = 100;
let opt = Some(n);
if let Some(p) = opt {
// do something with p
}
我们将{{1}称为Some
和None
构造子,因为它们各自产生类型为Option
的值。同样,您可以将Option
视为参考的构造函数。而且语法是对称的:
&
您可以在将值绑定到变量的任何地方使用此功能,这种情况发生在各处。例如:
let n = 100;
let reference = &n;
if let &p = reference {
// do something with p
}
,如上所述
if let
表达式:
match
在函数自变量中:
match opt {
Some(1) => { ... },
Some(p) => { ... },
None => { ... },
}
match reference {
&1 => { ... },
&p => { ... },
}
循环:
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
(表达式),编译器从中推断出n
是i32
。
各种模式都会发生类似的情况,例如,if let Some (x) = Some (42) { /* … */ }
中的模式匹配时,我们说Some (x)
是Some (42)
,因此x
是42。 / p>