我想做如下工作:
use std::ops::Add;
trait CanBeAdded: Sized where f64: Add<Self> {}
fn add2<X: CanBeAdded>(x: X) {}
fn main() {}
以上编译失败:
error[E0277]: the trait bound `f64: std::ops::Add<X>` is not satisfied
--> src/main.rs:5:1
|
5 | fn add2<X: CanBeAdded>(x: X) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Add<X>` is not implemented for `f64`
|
= help: consider adding a `where f64: std::ops::Add<X>` bound
= note: required by `CanBeAdded`
Playground link
我试图通过一个特性来断定某些
impl
的存在:即X: CanBeAdded
暗示f64: Add<X>
。虽然我可以像这样给函数的where子句添加边界:fn add2<X>(x: X) where f64: Add<X> { }
我有很多这样的球,所以很难控制,我不想一遍又一遍地重复这些球。有好的解决办法吗?例如,是否可以包含扩展为一系列
where
子句的宏? 最佳答案
实际上,随机类型X
不太可能是这样的f64: Add<X>
。
考虑到f64
是一个内置的模块,唯一可以为Add
定义f64
实现的模块是定义Add
的模块。我们可以查看listed implementations here:impl Add<f64> for f64
impl<'a> Add<&'a f64> for f64
仅此而已。
尽管如此,如果这是你想要的,你可以用不同的方式来定义特质。
首先,我们定义了一个新的标记性状。它本身很无趣,因为它完全没有方法:
trait ReverseAdd<T> { type Output; }
然后,我们添加了一个覆盖实现,以自动实现实现
Add
的任何类型的trait,但是关系颠倒了:impl<T, U> ReverseAdd<T> for U where T: Add<U> {
type Output = <T as Add<U>>::Output;
}
最后,我们用它作为我们的边界:
fn add2<X: ReverseAdd<f64>>(x: X) {
}
关于rust - 将类型之间的关系指定为特征或宏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41755504/