rust 所有trait对象的默认trait方法实现

dtcbnfnu  于 2023-11-19  发布在  其他
关注(0)|答案(1)|浏览(131)

我有一个trait MyTrait,我希望所有的trait对象&dyn MyTrait都能相互比较,而不能与其他任何东西比较。
问题是我需要在任何地方使用MyTraitComparable,而不是MyTrait。有没有办法解决这个问题?

use std::any::Any;

trait MyTrait {}

trait MyTraitComparable: MyTrait {
    fn as_any(&self) -> &dyn Any;

    fn equals(&self, other: &dyn MyTraitComparable) -> bool;
}

impl<S: 'static + MyTrait + PartialEq> MyTraitComparable for S {
    fn as_any(&self) -> &dyn Any {
        self as &dyn Any
    }

    fn equals(&self, other: &dyn MyTraitComparable) -> 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 {
        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: &dyn MyTraitComparable, another_obj: &dyn MyTraitComparable) -> bool {
    obj.equals(another_obj)
}

字符串
我尝试将as_anyequals迁移到MyTrait并提供默认实现,但是

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

px9o7tmv1#

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

#![feature(specialization)]

use std::any::Any;

trait MyTrait {
    fn as_any(&self) -> &dyn Any;
    fn equals(&self, other: &dyn MyTrait) -> bool;
}

default impl<S: 'static + PartialEq> MyTrait for S {
    default fn as_any(&self) -> &dyn Any {
        self as &dyn Any
    }

    default fn equals(&self, other: &dyn 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 {
        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: &dyn MyTrait, another_obj: &dyn MyTrait) -> bool {
    obj.equals(another_obj)
}

字符串

相关问题