你如何实现T的一个特征,其中T:Foo或Bar



在rust中,您可以为任何实现其他特征组合的类型自动实现特征。Ie:

impl<T: Foo + Bar> SomeTrait for T {
some_function(&self) {
/*...*/
}
}

我要做的是定义一个关系,其中FooBar,足以自己实现SomeTrait。基本上是这样的:

impl<T: Foo> SomeTrait for T {
some_function(&self) {
/*...*/
}
}
impl<T: Bar> SomeTrait for T {
some_function(&self) {
/*...*/
}
}

这不会编译,因为你要为T实现SomeTrait两次,编译器不可能知道在T: Foo + Bar的情况下该怎么做,但能够做到这一点真的很好。

有没有办法";摘要";围绕这个问题,以便我可以在实现FooBarT上调用some_function()?还是我只能选择一个实现?

如果夜间使用,则可以使用marker_trait_attr功能。它允许您为具有属性#[marker]的特征设置重叠的impl。请注意,该特征不应该有关联项,它必须为空。

因此,您可以定义一个标记特征FooOrBar(我在一个私有模块中创建了它,所以它是密封的,人们不能手动实现它(:

#![feature(marker_trait_attr)]
mod private {
#[marker]
pub trait FooOrBar {}
impl<T: super::Foo> FooOrBar for T {}
impl<T: super::Bar> FooOrBar for T {}
}

然后为实现FooOrBar:的任何类型实现特征SomeTrait

impl<T: private::FooOrBar> SomeTrait for T {
fn foo(&self) { /* ... */ }
}

游乐场。

不幸的是,对于稳定来说,我认为除了重新设计之外别无选择。

事实证明,在成为一项功能之前,有一些安全属性需要认真考虑。

唯一真正接近我所追求的是使用专业化功能,这是不稳定的,原因有很多,我有点无法理解。

不幸的是,这似乎意味着特征并不像我最初想象的那样强大,但应该有其他方法来处理这种情况。

最新更新