问题描述
我有一个特征MyTrait
,并且我希望所有特征对象&MyTrait
彼此可比,并且别无其他.我现在基于如何测试特征对象之间的相等性?.
I have a trait MyTrait
, and I want all trait objects &MyTrait
to be comparable to each other and to nothing else. I have that now based on How to test for equality between trait objects?.
问题是我需要在所有地方都使用MyTraitComparable
,而不是MyTrait
.有办法解决这个问题吗?
The problem is that I need to use MyTraitComparable
everywhere, instead of MyTrait
. Is there a way to get around this?
use std::any::Any;
trait MyTrait {}
trait MyTraitComparable: MyTrait {
fn as_any(&self) -> &Any;
fn equals(&self, other: &MyTraitComparable) -> bool;
}
impl<S: 'static + MyTrait + PartialEq> MyTraitComparable for S {
fn as_any(&self) -> &Any {
return self as &Any;
}
fn equals(&self, other: &MyTraitComparable) -> bool {
return match other.as_any().downcast_ref::<S>() {
None => false,
Some(a) => self == a,
};
}
}
#[derive(PartialEq)]
struct MyObj {
a: i32,
}
impl MyObj {
fn new(a: i32) -> MyObj {
return MyObj { a };
}
}
impl MyTrait for MyObj {}
fn main() {
assert!(as_trait_obj_and_compare(&MyObj::new(1), &MyObj::new(1)));
}
fn as_trait_obj_and_compare(obj: &MyTraitComparable, another_obj: &MyTraitComparable) -> bool {
obj.equals(another_obj)
}
我尝试将as_any
和equals
移到MyTrait
并提供默认实现,但是
I tried moving as_any
and equals
to MyTrait
and providing a default implementation, but
- 在这种情况下,我认为我不能使用
self
,所以它不起作用. - 如果使用
trait MyTrait: PartialEq
,则无法再创建特征对象.
- I don't think I can use
self
in that case, so it doesn't work. - If I use
trait MyTrait: PartialEq
then I can't create trait objects anymore.
推荐答案
如果您愿意使用夜间编译器和不稳定的功能,则可以使用专业化,避免具有两个特征:
If you're willing to use a nightly compiler and unstable features, you can use specialization to avoid having two traits:
#![feature(specialization)]
use std::any::Any;
trait MyTrait {
fn as_any(&self) -> &Any;
fn equals(&self, other: &MyTrait) -> bool;
}
default impl<S: 'static + PartialEq> MyTrait for S {
default fn as_any(&self) -> &Any {
return self as &Any;
}
default fn equals(&self, other: &MyTrait) -> bool {
match other.as_any().downcast_ref::<S>() {
None => false,
Some(a) => self == a,
}
}
}
#[derive(PartialEq)]
struct MyObj {
a: i32,
}
impl MyObj {
fn new(a: i32) -> MyObj {
return MyObj { a };
}
}
impl MyTrait for MyObj {}
fn main() {
assert!(as_trait_obj_and_compare(&MyObj::new(1), &MyObj::new(1)));
}
fn as_trait_obj_and_compare(obj: &MyTrait, another_obj: &MyTrait) -> bool {
obj.equals(another_obj)
}
这篇关于所有特征对象的默认特征方法实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!