-1

Was trying to write a generic function wich fills Vector in range

fn fill_vec<T: From<usize> + Copy>(target: &mut Vec<T>, to: usize, step: usize) {
    let mut start  = 0_usize;
    for i in 0..to {
        if start >= to {
            break;
        } else {
            if start > 0 {
                target.push(T::from(start));
            }
            start += step;
        }
    };
}

But I got the error


error[E0277]: the trait bound `i32: std::convert::From<usize>` is not satisfied
  --> src/main.rs:28:14
fill_vec(&mut target, 30, 4);
   |              ^^^^^^^^^^^ the trait `std::convert::From<usize>` is not implemented for `i32`
Khatry
  • 37
  • 2
  • Can you try `fill_vec(&mut target, 30 as usize, 4 as usize)` ? – Obzi Sep 14 '20 at 19:31
  • The same thing. – Khatry Sep 14 '20 at 19:50
  • The error says it, `i32` does not implement `From`, because `usize` has a bigger range, and `From::from` is infallible. Would you consider using `TryFrom`? – rodrigo Sep 14 '20 at 20:00
  • 1
    Please [edit] the question with the minimal code necessary to reproduce the error. – trent Sep 14 '20 at 20:01
  • @rodrigo It works. Thanks. I thought about it too. That this could be the reason. But i was confused cuz this function works. I thouth numbers are have i32 type by default. ```rust fn adds(x: T, y: R) -> T where T: Copy + From + Add, R: Copy { x + T::from(y) } ``` – Khatry Sep 14 '20 at 21:01

1 Answers1

0

Indeed, you cannot implicitly convert from usize to i32. For this kind of cast (which could lead to truncation) you need the as keyword.

fn main() {
    let mut v: Vec<i32> = Vec::new();
    let a: usize = 123;

    // v.push(a);
    // expected `i32`, found `usize`

    // v.push(i32::from(a));
    // the trait `std::convert::From<usize>` is not implemented for `i32`

    v.push(a as i32); // cast
}

About your specific example, the num_traits crate might help.

fn fill_vec<T: num_traits::cast::FromPrimitive>(
    target: &mut Vec<T>,
    to: usize,
    step: usize,
) {
    let mut start = 0_usize;
    for i in 0..to {
        if start >= to {
            break;
        } else {
            if start > 0 {
                target.push(T::from_usize(start).unwrap());
            }
            start += step;
        }
    }
}
prog-fh
  • 13,492
  • 1
  • 15
  • 30