如何将 Rust 书中的“Vec 中的最大值”示例转换为不使用 Copy 特征?

War*_*ame 1 vector rust

我正在尝试完成2018 年 Rust 书中“留给读者”的练习。他们的示例 10-15 使用了Copytrait。但是,他们建议在没有的情况下实现相同的功能,Copy而我一直在为此苦苦挣扎。

没有Copy,我无法使用largest = list[0]. 编译器建议改用引用。我这样做,largest变成了一个&T. 然后编译器抱怨largest比较中使用的是 a &T, not T,所以我将其更改*largest为取消引用指针。这一切顺利,但随后偶然发现了largest = item,抱怨T而不是&T。我切换到largest = &item. 然后我收到一个我无法处理的错误:

error[E0597]: `item` does not live long enough
 --> src/main.rs:6:24
  |
6 |             largest = &item;
  |                        ^^^^ borrowed value does not live long enough
7 |         }
8 |     }
  |     - borrowed value only lives until here
  |
note: borrowed value must be valid for the anonymous lifetime #1 defined on the function body at 1:1...
Run Code Online (Sandbox Code Playgroud)

我不明白如何延长这个值的寿命。它在list.iter(). 如何在仅使用引用的同时扩展它?

这是我的代码供参考:

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

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

    largest
}
Run Code Online (Sandbox Code Playgroud)

Fra*_*gné 8

当您编写 时for &item,这会解构迭代器返回的每个引用,使item T. 你不想解构这些引用,你想保留它们!否则,当您引用 时item,您正在引用一个局部变量,您无法返回该变量,因为局部变量存在的时间不够长。

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

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

    largest
}
Run Code Online (Sandbox Code Playgroud)

还要注意我们如何直接比较引用,因为对实现类型的引用PartialOrd也实现了PartialOrd,将比较推迟到它们的所指对象(即它不是指针比较,与原始指针不同)。

  • 值得注意的是,这通常习惯上写为`list.iter().max().unwrap()` (3认同)