gpt4 book ai didi

`for...in` 循环中的 Rust 借用规则

转载 作者:行者123 更新时间:2023-12-03 11:26:01 26 4
gpt4 key购买 nike

为什么这三个print_max功能工作?哪一个是最佳实践?是 for number in number_list for number in number_list.iter() 的快捷方式?

fn main() {
let number_list = vec![34, 50, 25, 100, 65];

print_max_1(&number_list);
print_max_2(&number_list);
print_max_3(&number_list);
}

fn print_max_1(number_list: &[u16]) {
let mut largest = &number_list[0]; // borrow the first number
for number in number_list.iter() { // borrowing?
if number > largest {
largest = number;
}
}
println!("The largest number is {}", largest);
}

fn print_max_2(number_list: &[u16]) {
let mut largest = &number_list[0]; // borrow the first number
for number in number_list { // shortcut for .iter()?
if number > largest {
largest = number;
}
}
println!("The largest number is {}", largest);
}

fn print_max_3(number_list: &[u16]) {
let mut largest = number_list[0]; // copying?
for &number in number_list.iter() { // borrowing?
if number > largest { // no error
largest = number;
}
}
println!("The largest number is {}", largest);
}

为什么这行不通?

fn print_max_4(number_list: &[u16]) {
let mut largest = &number_list[0];
for &number in number_list {
if number > largest {
largest = number;
}
}
println!("The largest number is {}", largest);
}

错误消息说 largest&u16numberu16 .为什么不是 number &u16 ?

最佳答案

让我们一一解决这些问题。
print_max_1
在这里,largest是一个可变变量,它持有对 u16 的不可变引用。 (即它拥有 &u16 )。在循环内,number也是&u16其中,例如 largest , 借自 number_list .两者 numberlarger被隐式取消引用以执行比较。如果 number 引用的值大于 larger 引用的值,您存储了包含在 number 中的不可变引用的副本。进入 largest .
print_max_2
在这种情况下,由于 number_list本身就是借来的,分析print_max_2print_max_1 相同.
print_max_3
在这里,largestu16 .你是对的 number_list[0]是抄的,但值得注意的是,这个抄本便宜。在循环内,number_list 的每个元素直接复制存储在number .如 number大于 largest ,您将新的最大值直接存储在 largest 中.这是您编写的三个实现中最优化的,因为您消除了引用(即指针)引入的所有不必要的间接性。
print_max_4
再一次,您存储对 number_list 的第一个元素的引用。在 largest ,即 largest&u16 .类似地,就像 print_max_3 中的情况一样, numberu16 ,它将保存来自 number_list 的元素的副本.但是,正如您所指出的,此功能是问题子项。

在循环中,编译器会指出两个错误:

  • 您尝试比较两种没有 PartialOrder 的不同类型定义,即 largest这是一个 &u16number这是一个 u16 . Rust 不会试图通过这种比较来猜测你的意思,所以为了解决这个问题,你必须同时制作 numberlargest相同的类型。在这种情况下,您要做的是明确取消引用 largest使用 *运算符,它将允许您比较 u16它指向 u16包含在 number 中.最后的比较看起来像
    if number > *largest { ... }
  • 您尝试存储 u16&u16 类型的变量中,这是没有意义的。不幸的是,在这里你会碰到一堵墙。在循环中,您所拥有的只是您从 number_list 复制的数字的值。 ,但是 largest需要持有对 u16 的引用.我们不能简单地借number在这里(例如通过写 largest = &number ),因为 number将在循环结束时被丢弃(即超出范围)。解决的唯一方法是恢复到 print_max_2通过存储最大值本身而不是指向它的指针。

  • 至于是否 for number in number_listfor number in number_list.iter() 的快捷方式,答案是坚定的 .前者将拥有 number_list 的所有权,并且在每次迭代期间, number取得 number_list 中下一个值的所有权.相比之下,后者只执行借位,并且在循环的每次迭代中, number接收对 number_list 的下一个元素的不可变引用.

    在这种特定情况下,这两个操作看起来是相同的,因为获得不可变引用的所有权只需要制作一个副本,从而使原始所有者保持不变。如需更多信息,请参阅 this answer关于 .into_iter() 之间区别的相关问题和 .iter() .

    关于 `for...in` 循环中的 Rust 借用规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60461475/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com