Rust书上市10-16:期望类型`T`找到类型`&T`

Man*_*idt 5 rust

当我尝试实现以下修改时,我陷入了清单10-16:

如果我们改变返回类型&T而不是T更改函数体以返回引用,我们就不需要 Clone或者Copy特征边界,我们也不会进行任何堆分配.尝试自己实施这些替代解决方案!

我的代码是

use std::cmp::PartialOrd;

fn largest<T: PartialOrd>(list: &[T]) -> &T {
    let mut largest: &T = &list[0];

    for &item in list.iter() {
        if item > largest {
            largest = &item;
        }
    }

    largest
}

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

    let result = largest(&number_list);
    println!("The largest number is {}", result);

    let char_list = vec!['y', 'm', 'a', 'q'];

    let result = largest(&char_list);
    println!("The largest char is {}", result);
}
Run Code Online (Sandbox Code Playgroud)

我收到了错误

error[E0308]: mismatched types
 --> src/main.rs:7:19
  |
7 |         if item > largest {
  |                   ^^^^^^^ expected type parameter, found &T
  |
  = note: expected type `T`
             found type `&T`
Run Code Online (Sandbox Code Playgroud)

jus*_*nas 13

list.iter()给你一个迭代器,而不是对元素的引用list.

使用for &item in ...语法,特别是&item模式,您取消引用它并将其用作T.这可能是反直觉在第一,但&item在这种情况下做了相反的东西&item会在大多数其他情况下做的(例如传递给函数时).

但是,largest明确定义为a &T,因此在这种情况下,<运算符会尝试比较两种不同的类型:T&T

&从模式中删除它一切都解决了.

for item in list.iter() {
    if item > largest {
        largest = item;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 还要注意,“ for ...…中的&item”实际上试图将值移到“ item”中(因为“ T”不是“ Copy”),这是不允许的,因为我们无法移动借入的值。而且,如果我们添加一个绑定到T的Copy,我们将被允许在…中为&item进行操作,但这仍然没有用,因为我们无法在最大的存储中存储对item的引用。由于`item`是副本,因此仅在为其创建的循环迭代中有效。所以`for&item`在这里永远无法工作。 (2认同)