我有以下代码:
use std::ops::Div;
use std::ops::Mul;
#[derive(Debug)]
struct Foo<T> {
bar: T,
}
impl<T> Foo<T>
where
T: Div<Output = T> + Copy,
{
fn new(bar: T) -> Foo<T> {
let baz = Foo::baz(bar);
Foo { bar: bar / baz }
}
fn baz(bar: T) -> T {
unimplemented!();
}
}
impl<T> Mul for Foo<T>
where
T: Mul<Output = T>,
{
type Output = Foo<T>;
fn mul(self, other: Foo<T>) -> Foo<T> {
Foo::new(self.bar * other.bar)
}
}
然而,编译器抱怨:
error[E0277]: cannot divide `T` by `T`
--> src/main.rs:29:9
|
29 | Foo::new(self.bar * other.bar)
| ^^^^^^^^ no implementation for `T / T`
|
= help: the trait `std::ops::Div` is not implemented for `T`
= help: consider adding a `where T: std::ops::Div` bound
note: required by `<Foo<T>>::new`
--> src/main.rs:13:5
|
13 | fn new(bar: T) -> Foo<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
--> src/main.rs:29:9
|
29 | Foo::new(self.bar * other.bar)
| ^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
|
= help: consider adding a `where T: std::marker::Copy` bound
note: required by `<Foo<T>>::new`
--> src/main.rs:13:5
|
13 | fn new(bar: T) -> Foo<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^
这可以通过以下修改来解决:
impl<T> Mul for Foo<T>
where
T: Mul<Output = T> + Div<Output = T> + Copy,
为什么我需要将Div<Output = T>
和Copy
添加到Mul for Foo<T>
?由于:
Foo<T>
不应满足范围
impl<T> Foo<T>
where
T: Div<Output = T> + Copy,
答案 0 :(得分:4)
每个impl
块彼此完全不同,包括它们的特征边界 - 一个impl
块具有约束的事实对其他块没有任何意义。
在这种情况下,特征impl
的{{1}}块并不真正需要 Mul
特征,因为它可以构建{{1}直接:
Div
这只是因为您选择调用Foo
(具有impl<T> Mul for Foo<T>
where
T: Mul<Output = T>,
{
type Output = Foo<T>;
fn mul(self, other: Foo<T>) -> Foo<T> {
Foo { bar: self.bar * other.bar }
}
}
和Foo::new
要求),Div
的原始版本无法编译。这在概念上与这个普通函数相同,它也不需要Copy
或Mul
:
Copy
请注意,我说过“Div
阻止”,而非“固有fn x<T>(a: T) -> Foo<T> {
Foo::new(a)
}
阻止”或“特征impl
阻止”。您可以拥有多个具有不同边界的固有impl
块:
impl
这允许类型具有仅在满足某些条件时才适用的函数。
另见: