简体   繁体   中英

How to return a reference without requiring Copy trait?

The Rust Programming Language has an example function that returns the largest element of a slice . It is mentioned that instead of returning the value, it should be possible to return a reference to that value which would allow us to use this function with types that do not implement the Copy trait.

The initial function that returns the value looks like this:

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

    for &item in list {
        if item > largest {
            largest = item;
        }
    }
    largest
}

I've been trying to modify it for a while now in order to return a pointer to that value instead of the value itself. I'm thinking this could also be implemented using the index, but I was wondering if there was no other way to proceed like in this attempt:

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

    for &item in list {
        if item > *largest {
            largest = &item;
        }
    }
    largest
}

This code does not compile and the compiler keeps panicking since I'm obviously missing something. In this instance it refuses to apply the binary operation '>', even though I'm "following" so to speak the the pointer that is largest to the value it represents:

error[E0369]: binary operation `>` cannot be applied to type `T`
 --> src/lib.rs:8:17
  |
8 |         if item > *largest {
  |            ---- ^ -------- T
  |            |
  |            T
  |
help: consider further restricting type parameter `T`
  |
3 |     &'a T: PartialOrd, T: std::cmp::PartialOrd
  |                      ^^^^^^^^^^^^^^^^^^^^^^^^^

I'd be grateful if someone had a hint as to what direction I should poke in order to get this approach to work, if possible at all?

While not being much of a surprise, this turned out to be a silly mistake: The item in the iteration didn't need to be a reference, and largest most certainly didn't need to be dereferenced. Here's the fixed version of that code:

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

    for item in list {
        if item > largest {
            largest = &item;
        }
    }
    largest
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM