Home > Software design >  Rust consider specifying the type argument in the function call: `::<T>`
Rust consider specifying the type argument in the function call: `::<T>`

Time:11-22

I simply want to call this function from imageproc crate. Right now i'm doing it like this:

let mut contours = find_contours_with_threshold(&src_image.to_luma8(), 10);

And i keep getting this error:

error[E0283]: type annotations needed
  --> src/main.rs:77:24
   |
77 |     let mut contours = find_contours_with_threshold(&src_image.to_luma8(), 10);
   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `find_contours_with_threshold`
   |
   = note: cannot satisfy `_: Num`
note: required by a bound in `find_contours_with_threshold`
  --> /home/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/imageproc-0.23.0/src/contours.rs:61:8
   |
61 |     T: Num   NumCast   Copy   PartialEq   Eq,
   |        ^^^ required by this bound in `find_contours_with_threshold`
help: consider specifying the type argument in the function call
   |
77 |     let mut contours = find_contours_with_threshold::<T>(&src_image.to_luma8(), 10);
   |                                                         

I understand that rust is not able to figure out what to expect as a result of that function call. In the documentation it should return a Vec<Contour<T>> where T: Num NumCast Copy PartialEq Eq but i don't know how to transpose that in my code.

I've tried doing it this way: let mut contours: Vec<Contour<dyn Num NumCast Copy PartialEq Eq>> = find_contours_with_threshold(&src_image.to_luma8(), 10); but i still don't understand what i'm doing so any help would be great.

Is it something like too many values to unpack in python? i should have done something like let x, y, z = find_contours..()?

CodePudding user response:

There is a type parameter T, which has some trait bounds (Num, NumCast, etc), and it's unconstrained.

Sure, it could be i32, but you could also define a custom type:

#[derive(Copy, Clone)]
struct MySillyNumber;

impl Num for MySillyNumber {}

// the rest of the required traits

and that's just as vaild a type for T as i32.

You need to tell rustc what T is. You can do it in a few ways:

  • turbofish: find_contours_with_threshold::<i32>()
  • explicit type ascription: let x: Vec<Contour<i32>> = find_contours_with_threshold()
  • passing it to a function:
fn main() {
  let x = find_contours_with_threshold();
  foo(x);
}

fn foo(x: Vec<Contour<i32>>) {}
  • or really any other way that gives rustc a concrete type to substitute for T.

Note, this is different to using Vec<Contour<dyn Num ...>>. This will turn the elements into "trait objects", which uses dynamic dispatch (with a vtable) to perform runtime polymorphism. This probably isn't what you want, in large part because dyn Trait doesn't have a known size, which means it can't appear on the stack without using a pointer of some kind. And while Vec is arguably a smart pointer, it requires that the contents have a fixed size, since it relies on this for indexing.

  • Related