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.