【问题标题】:Rust consider specifying the type argument in the function call: `::<T>`Rust 考虑在函数调用中指定类型参数:`::<T>`
【发布时间】:2022-11-22 04:51:03
【问题描述】:

我只想从imageproc crate 调用this function。现在我这样做:

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

而且我不断收到此错误:

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

我知道 Rust 无法弄清楚该函数调用的结果是什么。在文档中它应该返回 Vec&lt;Contour&lt;T&gt;&gt; where T: Num + NumCast + Copy + PartialEq + Eq 但我不知道如何在我的代码中转置它。

我试过这样做:let mut contours: Vec&lt;Contour&lt;dyn Num + NumCast + Copy + PartialEq + Eq&gt;&gt; = find_contours_with_threshold(&amp;src_image.to_luma8(), 10); 但我仍然不明白我在做什么所以任何帮助都会很棒。

在 python 中解压是不是有太多的值?我应该做类似let x, y, z = find_contours..()的事情吗?

【问题讨论】:

  • 如果您使用let mut contours = find_contours_with_threshold::&lt;i32&gt;(&amp;src_image.to_luma8(), 10);(或其他一些适当的整数类型)会发生什么?那样有用吗?我不熟悉那个图书馆,但它要求具体的输入 Contour 不受限制。
  • @KevinAnderson 它确实有效。谢谢!该特定类型不应该来自Num, NumCast, Copy, PartialEq, Eq吗?
  • @Mike Num, NumCast, Copy, ... 是特质。绑定 T: Num + NumCast + ... 意味着类型 T 必须具有这些特征的实现。满足这种界限的一种类型是i32,但是,它不是唯一的。编译器消息意味着它无法推断哪个输入你想要的。
  • @BlackBeans 感谢您的解释,帮助很大!

标签: image-processing rust


【解决方案1】:

有一个类型参数 T,它有一些特征边界(NumNumCast 等),并且不受约束。

当然,它可以是i32,但您也可以定义一个自定义类型:

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

impl Num for MySillyNumber {}

// the rest of the required traits

这与 Ti32 一样有效。

你需要告诉 rustc T 是什么。您可以通过几种方式做到这一点:

  • 涡轮鱼:find_contours_with_threshold::&lt;i32&gt;()
  • 显式类型归属:let x: Vec&lt;Contour&lt;i32&gt;&gt; = find_contours_with_threshold()
  • 将其传递给函数:
fn main() {
  let x = find_contours_with_threshold();
  foo(x);
}

fn foo(x: Vec<Contour<i32>>) {}
  • 或任何其他方式,让 rustc 有一个具体类型来替代 T

请注意,这与使用 Vec&lt;Contour&lt;dyn Num + ...&gt;&gt; 不同。这会将元素变成“特征对象”,它使用动态调度(使用 vtable)来执行运行时多态性。这可能不是您想要的,很大程度上是因为 dyn Trait 没有已知大小,这意味着它不能在不使用某种指针的情况下出现在堆栈上。虽然 Vec 可以说是一个智能指针,但它要求内容具有固定大小,因为它依赖于此进行索引。

【讨论】:

  • 谢谢 @cameron1024 - 你将其表述为答案,并且比我在评论中更加确定。我很欣赏你如何扩展各种典型的方式来指定它。对于来自 C++ 的人(即:我),将模板类型放在返回值是 Rust 中的一种常见模式,但对我来说真的很奇怪,因为 C++ 函数重载的规则意味着参数是,但不是返回类型。不同的构造、重载与模板,但它仍然是我大脑工作的默认方式,所以这种事情让我有点不高兴。
猜你喜欢
  • 2019-09-21
  • 1970-01-01
  • 2020-10-13
  • 2017-04-23
  • 1970-01-01
  • 2015-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多