Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rust book listing 10-16: expected type `T` found type `&T`

Tags:

rust

I am stuck at Listing 10-16 when I try to implement the following modification:

If we change the return type to be &T instead of T and change the body of the function to return a reference, we wouldn’t need either the Clone or Copy trait bounds and we wouldn’t be doing any heap allocations. Try implementing these alternate solutions on your own!

My code is

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);
}

I get the error

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`
like image 350
Manuel Schmidt Avatar asked Jan 10 '18 15:01

Manuel Schmidt


1 Answers

list.iter() gives you an iterator over references to elements of list.

Using the for &item in ... syntax, notably the &item pattern, you dereference it and use it as a T. It might be counter-intuitive at first, but &item in this case does the opposite of what &item would do in most other contexts (e.g. when passing to a function).

However, largest is explicitly defined as a &T, so in this case the < operator tries to compare two different types: T and &T

Remove the & from the pattern and it all works out.

for item in list.iter() {
    if item > largest {
        largest = item;
    }
}
like image 124
justinas Avatar answered Sep 18 '22 01:09

justinas