Reference “和”的目的是什么在循环变量之前?
列表中的代码Reference “和”的目的是什么在循环变量之前?,reference,rust,pattern-matching,destructuring,ampersand,Reference,Rust,Pattern Matching,Destructuring,Ampersand,列表中的代码&i中的&code>的目的是什么?如果我删除&,它会在最大=I中产生错误,因为它们的类型不匹配(其中I是&32,而I是i32)。但是&i如何将i转换为i32 fn最大(列表:&[i32])->i32{ println!(“{:?}”,列表); 让mut最大=列表[0]; 列表中的for&i{ 如果我>最大的{ 最大=i; } } 最大的 } fn main(){ 让hey=vec![1,3,2,6,90,67788,12,34,54,32]; println!(“最大的数字是:{}”
&i中的&code>的目的是什么?如果我删除&
,它会在最大=I
中产生错误,因为它们的类型不匹配(其中I
是&32
,而I
是i32
)。但是&i
如何将i
转换为i32
fn最大(列表:&[i32])->i32{
println!(“{:?}”,列表);
让mut最大=列表[0];
列表中的for&i{
如果我>最大的{
最大=i;
}
}
最大的
}
fn main(){
让hey=vec![1,3,2,6,90,67788,12,34,54,32];
println!(“最大的数字是:{}”,最大的(&hey));
}
看起来它似乎在某种程度上取消了引用,但为什么在下面的代码中,它不起作用呢
fn main() {
let mut hey: i32 = 32;
let x: i32 = 2;
hey = &&x;
}
它说:
4 |嘿=&&x;
|^^^应为i32,找到(&i32)
|
=注意:应为'i32'类型`
找到类型`&&i32`
因此,通常当您对列表中的i使用时,循环变量i
的类型为&i32
但是,当您在列表中为&i使用时,您并没有取消引用任何内容,而是使用模式匹配来显式地分解引用,这将使i
仅为i32
类型
请参阅有关for-loop变量和我们在这里使用的参数的Rust文档。另请参见上的“锈蚀示例”一章
解决此问题的另一种方法是保持i
不变,然后将i
与最大值的引用进行比较,然后在分配给最大值之前取消引用i
:
fn largest(list: &[i32]) -> i32 {
println!("{:?}", list);
let mut largest = list[0];
for i in list {
if i > &largest {
largest = *i;
}
}
largest
}
这根本不起作用,因为在这里您将hey
,这是一个i32
,分配给对i32
的引用的引用。这与循环变量情况下的模式匹配和分解无关。这是分解的效果。我不会在这里完全描述该功能,但简而言之:
在许多语法上下文中(let
bindings、for
循环、函数参数等),Rust需要一种“模式”。此模式可以是一个简单的变量名,但也可以包含一些“解构元素”,如&
。Rust会将一个值绑定到此模式。一个简单的例子如下:
let(a,b)=('x',true);
右侧有一个类型为(char,bool)
(元组)的值。此值绑定到左手模式((a,b)
)。由于模式(特别是元组)中已经定义了一个“结构”,因此该结构将被删除并绑定到元组的元素。因此,a
的类型是char
,b
的类型是bool
这适用于两种结构,包括阵列:
让[x]=[true];
同样,在右侧,我们有一个类型为[bool;1]
(数组)的值,在左侧,我们有一个数组形式的模式。单个数组元素绑定到x
,这意味着x
的类型是bool
,而不是[bool;1]
不出所料,这也适用于参考
设foo=0u32;
设r=&foo;
让&c=&foo;
这里,foo
具有类型u32
,因此表达式&foo
具有类型&u32
。r
的类型也是&u32
,因为它是一个简单的let
绑定。然而,c
的类型是u32
!这是因为“引用已被模式分解/删除”
一个常见的误解是模式中的语法与表达式中相同语法的效果完全相反如果变量a
的类型为[T;1]
,则表达式[a]
的类型为[T;1]
→ 它增加了一些东西。但是,如果将a
绑定到模式[c]
,则y
具有类型T
→ 它可以移除东西
设a=[true];//`a``的类型:`[bool;1]`
设b=[a];//`b`的类型:`[[bool;1];1]`
设[c]=a;//'c'的类型:`bool`
这也解释了你的问题:
看起来它似乎在某种程度上取消了引用,但为什么在下面的代码中,它不起作用呢
fn main() {
let mut hey: i32 = 32;
let x: i32 = 2;
hey = &&x;
}
fn main(){
让mut-hey:i32=32;
设x:i32=2;
嘿=&&x;
}
因为您在表达式端使用了&
,它在表达式端添加了一层引用
关于循环的最后一点:当迭代一个切片时(就像您在这里所做的),迭代器会产生对切片元素的引用。因此,对于列表{}
中的i,i
的类型为&i32
。但赋值最大=i
需要在右侧安装一个i32
。您可以通过两种方式实现这一点:通过解引用操作符*
(即最大=*i;
)解引用i
)或在循环模式中分解引用(即for&i in list{}
)
相关问题:
与您的问题无关,但函数可以重写为list.iter().copied().max().expect(“空列表”)
。可能对你有用。是相关的。谢谢你这么清楚的回答。我认为将解构视为代数“取消”操作可能会有所帮助。例如,在let&c=&foo
-如果“取消”&
,则c
设置为foo
。“c的参考设置为foo的参考”,因此c
设置为foo
。感谢您的帮助