fn largest(num_list: &[i32]) -> i32 {
let mut largest = num_list[0];
for &num in num_list {
if num > largest {
largest = num
}
}
largest
}
fn largest2(num_list: &[i32]) -> i32 {
let mut largest = num_list[0];
for num in num_list {
if num > &largest {
largest = *num
}
}
largest
}
fn main() {
let num_list = vec![30, 20, 10, 60, 50, 40];
let largest = largest(&num_list);
let largest2 = largest2(&num_list);
println!("The largest number in num_list fn is: {}.", largest);
println!("The largest number in num_list fn is: {}.", largest2);
}
可以看到最大的有一些细微的差异和largest2。有人能帮助我理解这里的差异,为什么两个代码样本实际上功能相同?
两个示例之间的主要区别源于您的循环语句,for num in num_list
vsfor &num in num_list
。首先,重要的是要理解它们等价于for [...] in num_list.iter()
,即它们迭代num_list
元素的引用。然后将这些类型为&i32
的引用赋值给num
或&num
。在第一种情况下,我们只有一个直接赋值,因此是num: &i32
。在第二种情况下,有一个不可辩驳的赋值,将num
绑定到数字,因此是num: i32
。顺便说一句,这是可能的,因为即使你试图从借用,i32: Copy
移出一个值,所以Rust编译它很好。
剩下的只是适应:要么你使用&i32
,要么直接使用i32
。例如,当num: &i32
和largest
比较时,你应该取消对num
的引用,然后再比较,得到*num > largest
。然而,num > &largest
也可以工作,因为Rust知道如何通过解引用来比较两个&i32
(因此它实际上会生成*num > largest
)。同样地,当你给largest
赋值时,你必须赋值一个i32
,所以你取消对num
:largest = *num
的引用。
这很容易理解,为什么这两段代码做同样的事情:在一个版本中,您将指针的值复制到num
中的整数,然后使用它,而在另一个版本中,您保留num
中的解引用,每次需要使用它时只需解引用它。