From trait only works on values, but I have references

Viewed 89

I want to turn a list of any numeric type into a list of floats. The following code fails to compile:

#[cfg(test)]
mod tests {
    #[test]
    fn test_int_to_float() {
        use super::int_to_float;
        assert_eq!(vec![0.0, 1.0, 2.0], int_to_float(&[0, 1, 2]));
    }
}

pub fn int_to_float<I>(xs: I) -> Vec<f64>
where
    I: IntoIterator,
    f64: From<I::Item>,
{
    xs.into_iter().map(f64::from).collect()
}

The error message is

error[E0277]: the trait bound `f64: std::convert::From<&{integer}>` is not satisfied
 --> src/main.rs:6:41
  |
6 |         assert_eq!(vec![0.0, 1.0, 2.0], int_to_float(&[0, 1, 2]));
  |                                         ^^^^^^^^^^^^ the trait `std::convert::From<&{integer}>` is not implemented for `f64`
  |
  = help: the following implementations were found:
            <f64 as std::convert::From<i8>>
            <f64 as std::convert::From<i16>>
            <f64 as std::convert::From<f32>>
            <f64 as std::convert::From<u16>>
          and 3 others
  = note: required by `int_to_float`

I understand that I::Item is a reference to an i32 (&i32), but f64::from is only implemented for values. How do I get this to compile?

1 Answers

Because you accept anything that can be turned into an iterator, you can convert each item in the iterator into the dereferenced form. The easiest thing to do here is to use Iterator::cloned:

assert_eq!(vec![0.0, 1.0, 2.0], int_to_float([0, 1, 2].iter().cloned()));
Related