循环变量前加“&”的目的是什么?
What is the purpose of `&` before the loop variable?
代码&i in list
中&
的作用是什么?如果我删除 &
,它会在 largest = i
中产生错误,因为它们的类型不匹配(其中 i
是 &32
,i
是 i32
).但是&i
如何将i
转换成i32
呢?
fn largest(list: &[i32]) -> i32 {
println!("{:?}", list);
let mut largest = list[0];
for &i in list {
if i > largest {
largest = i;
}
}
largest
}
fn main() {
let hey = vec![1, 3, 2, 6, 90, 67, 788, 12, 34, 54, 32];
println!("The largest number is: {}", largest(&hey));
}
它似乎以某种方式取消引用,但为什么在下面的代码中它不起作用?
fn main() {
let mut hey: i32 = 32;
let x: i32 = 2;
hey = &&x;
}
它说:
4 | hey = &&x;
| ^^^ expected i32, found &&i32
|
= note: expected type `i32`
found type `&&i32`
所以通常当你使用 for i in list
时,循环变量 i
的类型是 &i32
.
但是当你使用 for &i in list
时,你并不是 取消引用 任何东西,而是 你正在使用模式匹配来显式 destructure 引用 并且这将使 i
只是类型 i32
.
查看有关 for-loop 循环变量的 Rust 文档 being a pattern and the reference pattern that we are using here. See also the Rust By Example chapter on destructuring pointers。
解决此问题的另一种方法是保持 i
不变,然后将 i
与对 largest
的引用进行比较,然后取消引用 i
] 在分配给 largest
之前:
fn largest(list: &[i32]) -> i32 {
println!("{:?}", list);
let mut largest = list[0];
for i in list {
if i > &largest {
largest = *i;
}
}
largest
}
fn main() {
let mut hey: i32 = 32;
let x: i32 = 2;
hey = &&x;
}
这根本行不通,因为在这里您要将 hey
(即 i32
)分配给对 i32
的引用的引用。这与循环变量情况下的模式匹配和解构完全无关。
这是解构的效果。我不会在这里完全描述该功能,但简而言之:
在许多语法上下文中(let
绑定,for
循环,函数参数,...),Rust 需要一个“模式”。这个模式可以是一个简单的变量名,但也可以包含一些“解构元素”,比如&
。然后 Rust 会为这个模式绑定一个值。一个简单的例子是这样的:
let (a, b) = ('x', true);
右侧有一个 (char, bool)
类型的值(一个元组)。此值绑定到左手模式 ((a, b)
)。由于模式中已经定义了一个“结构”(特别是元组),该结构被删除并且 a
和 b
绑定到元组的元素。因此,a
的类型是 char
而 b
的类型是 bool
.
这适用于几个结构,包括数组:
let [x] = [true];
同样,在右侧我们有一个 [bool; 1]
类型的值(一个数组),在左侧我们有一个数组形式的模式。单个数组元素绑定x
,意思是x
的类型是bool
,不是 [bool; 1]
!
毫不奇怪,这也适用于参考!
let foo = 0u32;
let r = &foo;
let &c = &foo;
此处,foo
的类型为 u32
,因此,表达式 &foo
的类型为 &u32
。 r
的类型也是 &u32
,因为它是一个简单的 let
绑定。然而 c
的类型是 u32
!那是因为模式的“引用是 destructured/removed”。
一个常见的误解是,模式中的语法与相同语法在表达式中的效果完全相反! 如果您有一个 a
类型的变量[T; 1]
,那么表达式 [a]
的类型是 [[T; 1]; 1]
→ 它 添加 东西。但是,如果将 a
绑定到模式 [c]
,则 y
具有类型 T
→ 它 删除 东西。
let a = [true]; // type of `a`: `[bool; 1]`
let b = [a]; // type of `b`: `[[bool; 1]; 1]`
let [c] = a; // type of `c`: `bool`
这也解释了你的问题:
It seems like it is somehow dereferencing, but then why in the below code, it is not working?
fn main() {
let mut hey:i32 = 32;
let x:i32 = 2;
hey = &&x;
}
因为您在表达式端使用了 &
,它 添加了 一层引用。
最后关于你的循环:当迭代一个切片时(就像你在这里所做的那样),迭代器产生对切片元素的引用。所以在 for i in list {}
的情况下,i
的类型是 &i32
。但是赋值 largest = i;
需要在右侧有一个 i32
。您可以通过两种方式实现此目的:通过取消引用运算符 *
(即 largest = *i;
)取消引用 i
或在循环模式中解构引用(即 for &i in list {}
)。
相关问题:
代码&i in list
中&
的作用是什么?如果我删除 &
,它会在 largest = i
中产生错误,因为它们的类型不匹配(其中 i
是 &32
,i
是 i32
).但是&i
如何将i
转换成i32
呢?
fn largest(list: &[i32]) -> i32 {
println!("{:?}", list);
let mut largest = list[0];
for &i in list {
if i > largest {
largest = i;
}
}
largest
}
fn main() {
let hey = vec![1, 3, 2, 6, 90, 67, 788, 12, 34, 54, 32];
println!("The largest number is: {}", largest(&hey));
}
它似乎以某种方式取消引用,但为什么在下面的代码中它不起作用?
fn main() {
let mut hey: i32 = 32;
let x: i32 = 2;
hey = &&x;
}
它说:
4 | hey = &&x;
| ^^^ expected i32, found &&i32
|
= note: expected type `i32`
found type `&&i32`
所以通常当你使用 for i in list
时,循环变量 i
的类型是 &i32
.
但是当你使用 for &i in list
时,你并不是 取消引用 任何东西,而是 你正在使用模式匹配来显式 destructure 引用 并且这将使 i
只是类型 i32
.
查看有关 for-loop 循环变量的 Rust 文档 being a pattern and the reference pattern that we are using here. See also the Rust By Example chapter on destructuring pointers。
解决此问题的另一种方法是保持 i
不变,然后将 i
与对 largest
的引用进行比较,然后取消引用 i
] 在分配给 largest
之前:
fn largest(list: &[i32]) -> i32 {
println!("{:?}", list);
let mut largest = list[0];
for i in list {
if i > &largest {
largest = *i;
}
}
largest
}
fn main() { let mut hey: i32 = 32; let x: i32 = 2; hey = &&x; }
这根本行不通,因为在这里您要将 hey
(即 i32
)分配给对 i32
的引用的引用。这与循环变量情况下的模式匹配和解构完全无关。
这是解构的效果。我不会在这里完全描述该功能,但简而言之:
在许多语法上下文中(let
绑定,for
循环,函数参数,...),Rust 需要一个“模式”。这个模式可以是一个简单的变量名,但也可以包含一些“解构元素”,比如&
。然后 Rust 会为这个模式绑定一个值。一个简单的例子是这样的:
let (a, b) = ('x', true);
右侧有一个 (char, bool)
类型的值(一个元组)。此值绑定到左手模式 ((a, b)
)。由于模式中已经定义了一个“结构”(特别是元组),该结构被删除并且 a
和 b
绑定到元组的元素。因此,a
的类型是 char
而 b
的类型是 bool
.
这适用于几个结构,包括数组:
let [x] = [true];
同样,在右侧我们有一个 [bool; 1]
类型的值(一个数组),在左侧我们有一个数组形式的模式。单个数组元素绑定x
,意思是x
的类型是bool
,不是 [bool; 1]
!
毫不奇怪,这也适用于参考!
let foo = 0u32;
let r = &foo;
let &c = &foo;
此处,foo
的类型为 u32
,因此,表达式 &foo
的类型为 &u32
。 r
的类型也是 &u32
,因为它是一个简单的 let
绑定。然而 c
的类型是 u32
!那是因为模式的“引用是 destructured/removed”。
一个常见的误解是,模式中的语法与相同语法在表达式中的效果完全相反! 如果您有一个 a
类型的变量[T; 1]
,那么表达式 [a]
的类型是 [[T; 1]; 1]
→ 它 添加 东西。但是,如果将 a
绑定到模式 [c]
,则 y
具有类型 T
→ 它 删除 东西。
let a = [true]; // type of `a`: `[bool; 1]`
let b = [a]; // type of `b`: `[[bool; 1]; 1]`
let [c] = a; // type of `c`: `bool`
这也解释了你的问题:
It seems like it is somehow dereferencing, but then why in the below code, it is not working?
fn main() { let mut hey:i32 = 32; let x:i32 = 2; hey = &&x; }
因为您在表达式端使用了 &
,它 添加了 一层引用。
最后关于你的循环:当迭代一个切片时(就像你在这里所做的那样),迭代器产生对切片元素的引用。所以在 for i in list {}
的情况下,i
的类型是 &i32
。但是赋值 largest = i;
需要在右侧有一个 i32
。您可以通过两种方式实现此目的:通过取消引用运算符 *
(即 largest = *i;
)取消引用 i
或在循环模式中解构引用(即 for &i in list {}
)。
相关问题: