【问题标题】:Generic Implementation gets "cannot add 'T' to 'T' error通用实现得到“无法将'T'添加到'T'错误
【发布时间】:2020-06-22 20:10:07
【问题描述】:

我正在尝试通用实现,并尝试添加一个结构的 x 和 y 字段,它们都是 T 类型,

我在impl<T> Point<T> 下看到一条红色波浪线,还有以下错误消息...

cannot add `T` to `T`

no implementation for `T + T`

help: the trait `std::ops::Add` is not implemented for `T`

从我的代码中可以看出,我已经为类型T添加了特征std::ops::Add

如何让下面的代码工作?

struct Point<T>
where
  T: std::ops::Add<Output = T>,
{
  x: T,
  y: T,
}

impl Point<f32> {
  fn add_f32(&self) -> f32 {
    self.x + self.y
  }
}

//error
impl<T> Point<T> {
  fn add(&self) -> T
  where
    T: std::ops::Add<Output = T>,
  {
    self.x + self.y
  }
}

【问题讨论】:

  • 编译器实际上在这里可以进一步帮助您:“帮助:考虑限制类型参数T,然后是impl&lt;T: std::ops::Add&gt; Point&lt;T&gt; {。完成此操作后,您会发现一些其他问题需要解决(即 Add 按值接收其操作数,但您有对 &amp;self 的引用,而 T 不限于 Copy
  • 请注意,出现此问题是因为约束 T: Add&lt;Output = T&gt; 被放置在结构声明中。在这种情况下也可以省略,因为我们这里不需要它:struct Point&lt;T&gt; { x: T, y: T, }
  • 你是对的。在我删除结构定义中的 where 子句并删除 self.我将在这里输入工作代码

标签: rust


【解决方案1】:

这个问题有两种解决方案,各有优劣。

第一个解决方案是从结构定义中删除T: std::ops::Add&lt;Output = T&gt;绑定:

struct Point<T> {
  x: T,
  y: T,
}

这意味着如果T 没有实现AddPoint&lt;T&gt; 类型的add() 方法不可用。但是,您仍然可以创建这样的类型。如果你随后尝试在其上调用 add() 方法,Rust 将显示错误 - playground link

另一种解决方案是保持 trait bound,这意味着每次使用时都必须强制执行:

struct Point<T: Add<Output = T>> {
  x: T,
  y: T,
}

impl<T: Add<Output = T>> Point<T> {
//      ^^^^^^^^^^^^^^^ required
    ...
}

这意味着 Point&lt;T&gt; 只有在 T 实现 Add 时才能存在。如果类型 Point&lt;SomeTypeThatIsntAdd&gt; 根本没有意义或无用,您可以这样做。在某些情况下,它还改进了编译器诊断。

【讨论】:

  • 第二种方法由于其“病毒”效应而经常被避免。然后,该结构的每个 impl 块都需要包含该特征绑定,即使它与手头的实现无关。
  • 来自您的代码示例并基于 E_net4... 注释,因此似乎更好的做法是不要在结构上添加特征绑定,而是在实现上添加特征绑定
【解决方案2】:
struct Point<T> {
  x: T,
  y: T,
}

impl Point<f32> {
  fn add_f32(&self) -> f32 {
    self.x + self.y
  }
}

impl<T> Point<T> {
  fn add(self) -> T
  where
    T: std::ops::Add<Output = T>,
  {
    self.x + self.y
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    相关资源
    最近更新 更多