本文介绍了所有特征对象的默认特征方法实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个特征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_anyequals移到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)
}

这篇关于所有特征对象的默认特征方法实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-23 08:31