有没有一种方法可以通用地为智能指针中的对象(例如 Box
、Rc
等)的特征提供实现?
例子:
use std::borrow::Borrow;
use std::rc::Rc;
trait KindaEqual<Rhs = Self> {
fn kinda_equal(&self, other: &Rhs) -> bool;
}
// Nice to have (still need to copy-paste for each LHS container)
impl<T, Rhs, WrappedRhs> KindaEqual<WrappedRhs> for T
where
WrappedRhs: Borrow<Rhs>,
T: KindaEqual<Rhs>,
{
fn kinda_equal(&self, other: &WrappedRhs) -> bool {
self.kinda_equal(other.borrow())
}
}
// Best to have (handles both LHS and RHS containers)
impl<WrappedT, T, Rhs, WrappedRhs> KindaEqual<WrappedRhs> for WrappedT
where
WrappedRhs: Borrow<Rhs>,
WrappedT: Borrow<T>,
T: KindaEqual<Rhs>,
{
fn kinda_equal(&self, other: &WrappedRhs) -> bool {
self.borrow().kinda_equal(other.borrow())
}
}
impl KindaEqual for f64 {
fn kinda_equal(&self, other: &Self) -> bool {
num::abs(self - other) < 0.01f64
}
}
impl KindaEqual<u64> for f64 {
fn kinda_equal(&self, other: &u64) -> bool {
num::abs(self - *other as f64) < 1f64
}
}
fn main() {
assert!(3.141592654.kinda_equal(&3.14));
assert!(3.141592654.kinda_equal(&3));
assert!(3.141592654.kinda_equal(&Rc::new(3.14)));
}
上面给出了错误:
error[E0207]: the type parameter `Rhs` is not constrained by the impl trait, self type, or predicates
--> src/main.rs:9:9
|
9 | impl<T, Rhs, WrappedRhs> KindaEqual<WrappedRhs> for T
| ^^^ unconstrained type parameter
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
--> src/main.rs:20:16
|
20 | impl<WrappedT, T, Rhs, WrappedRhs> KindaEqual<WrappedRhs> for WrappedT
| ^ unconstrained type parameter
error[E0207]: the type parameter `Rhs` is not constrained by the impl trait, self type, or predicates
--> src/main.rs:20:19
|
20 | impl<WrappedT, T, Rhs, WrappedRhs> KindaEqual<WrappedRhs> for WrappedT
| ^^^ unconstrained type parameter
我读到过添加关联类型可能会修复它,但这是不可取的,因为它会强制使用特征来实现它。
- 这可以在没有关联类型的情况下解决吗? (最好)
- 这可以用关联类型解决吗?
最佳答案
/-- everything here
impl<Types...> Trait for Self
\-- has to appear here \-- or here
作为error message表示,Types...
必须受到 Trait
、Self
或 Trait
或 self
。
如果您可以为每个 LHS 容器复制粘贴,您可以将 Borrow
处理向下移动到函数本身,如下所示:
use std::borrow::Borrow;
trait KindaEqual<Rhs = Self> {
fn kinda_equal<R: Borrow<Rhs>>(&self, other: &R) -> bool;
}
impl KindaEqual<u32> for u32 {
fn kinda_equal<R: Borrow<u32>>(&self, other: &R) -> bool {
self == other.borrow()
}
}
// repeat for all supported containers
impl<T> KindaEqual<T> for Box<T>
where
T: KindaEqual<T>,
{
fn kinda_equal<R: Borrow<T>>(&self, other: &R) -> bool {
(&**self).kinda_equal(other.borrow())
}
}
关于generics - 有没有办法为智能指针中的对象通用地实现一个特征?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56537015/