在下面的代码中,我想在迭代之后保留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
而不是它解析的价值(如果双重参考甚至可能)。为什么会发生这种情况,&
的含义是否因环境而异?
它可以帮助将引用视为一种容器。为了比较,考虑Option
,我们可以使用模式匹配“解包”该值,例如在if let
语句中:
let n = 100;
let opt = Some(n);
if let Some(p) = opt {
// do something with p
}
我们将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) { ... }
for &p in iter_of_i32_refs {
...
}
也许more。
请注意,最后两个对Option
不起作用,因为如果找到None
而不是Some
它们会发生恐慌,但是引用不会发生因为它们只有一个构造函数&
。
&
的含义是否因环境而异?
希望如果你能将&
解释为构造函数而不是运算符,那么你会发现它的含义不会改变。 Rust的一个非常酷的功能是,您可以在表达式的右侧使用构造函数来创建值,并在左侧使用它们将它们分开(解构)。
除了其他语言(C ++)之外,&n
在这种情况下不是引用,而是模式匹配,这意味着这是期待引用。
与此相反的是ref n
,它会给你&&i32
作为一种类型。
闭包也是如此,例如
(0..).filter(|&idx| idx < 10)...
请注意,这将移动变量,例如对于没有实现Copy
特性的类型,你不能这样做。
我的困惑(并记住我没有涵盖模式)是我会期望,因为n:&i32,然后&n:&& i32而不是它解析为值(如果双重参考甚至可能)。为什么会发生这种情况,并且&的含义是否因环境而异?
当你进行模式匹配时(例如当你写for &n in &number_list
时),你并不是说n
是&i32
,而是你说&n
(模式)是&i32
(表达式),编译器推断n
是一个i32
。
类似的事情发生在各种模式中,例如当if let Some (x) = Some (42) { /* … */ }
中的模式匹配时,我们说Some (x)
是Some (42)
,因此x
是42。