所有特征对象的默认特征方法实现

时间:2018-03-24 15:02:17

标签: types rust traits default-implementation trait-objects

我有一个特征MyTrait,我希望所有特征对象&MyTrait可以相互比较,而不是别的。我现在基于How to test for equality between trait objects?

问题在于我需要在任何地方使用MyTraitComparable,而不是MyTrait。有办法解决这个问题吗?

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_anyequals移至MyTrait并提供默认实施,但

  • 在这种情况下我不认为我可以使用self,所以它不起作用。
  • 如果我使用trait MyTrait: PartialEq,那么我就不能再创建特质对象。

1 个答案:

答案 0 :(得分:2)

如果您愿意使用夜间编译器和不稳定的功能,可以使用specialization来避免使用两个特征:

<script>
var source = new EventSource("panic.php");
source.onmessage=function(event) {
    document.getElementById("panic_status").innerHTML=event.data;
};
</script>