特质实现冲突

问题描述 投票:0回答:1

我正在学习 Rust,并且很难将我的 C++ 架构思维方式转变为 Rust 架构世界。目前,我正在努力定义特征的通用功能以避免代码重复。

问题

trait CommonFunctionality {
    fn common_method(&self) -> i32;
}


trait SpecialFunctionality1 : CommonFunctionality {
    fn special_foo(&self) -> i32;  // defined in actual implementations
}
impl<T: SpecialFunctionality1> CommonFunctionality for T {
    fn common_method(&self) -> i32 {self.special_foo()}
}


trait SpecialFunctionality2 : CommonFunctionality {
    fn special_bar(&self) -> i32;  // defined in actual implementations
}
impl<T: SpecialFunctionality2> CommonFunctionality for T {
    fn common_method(&self) -> i32 {self.special_bar()}
}

我不想为我编写的每个实际结构实现

CommonFunctionality
。所以我有了在图书馆使用超级特征的想法。每个实现
SpecialFunctionality1
SpecialFunctionality2
的实际结构实现都可以获得
CommonFunctionality
,无需任何额外代码。不幸的是这不能编译。

编译器抛出:

error[E0119]: conflicting implementations of trait 'CommonFunctionality'

我发现了类似的问题描述,但其根本原因是类型无法区分,这里

impl<T: SpecialFunctionality1>
impl<T: SpecialFunctionality2>
显然是不同的类型(据我理解)。 当注释掉最后三行时,所有内容都会编译。

那么,谁能解释为什么这不能编译? 或者,有人对编码更好的模式有建议吗?

低效的解决方法

有效的是,当我仅针对其中一个专门特征实施

CommonFunctionality
时。

我的库中的特征可能如下所示:

trait CommonFunctionality {
    fn common_method(&self) -> i32;
}

trait SpecialFunctionality1 : CommonFunctionality {
    fn special_foo(&self) -> i32;
}
impl<T: SpecialFunctionality1> CommonFunctionality for T {
    fn common_method(&self) -> i32 {self.special_foo()}
}

trait SpecialFunctionality2 : CommonFunctionality {
    fn special_bar(&self) -> i32;
}

虽然

SpecialFunctionality1
的实际结构实现与
CommonFunctionality
完全解耦(同时仍然提供它):

struct MyStruct1 {
}

impl SpecialFunctionality1 for MyStruct1 {
    fn special_foo(&self) -> i32 {46}
}

SpecialFunctionality2
的实际结构实现与
CommonFunctionality
完全耦合:

struct MyStruct2 {
}

impl SpecialFunctionality2 for MyStruct1 {
    fn special_bar(&self) -> i32 {36}
}

impl CommonFunctionality for MyStruct2 {
    fn common_method(&self) -> i32 {self.special_bar()}
}

现在最后三行代码需要在从

SpecialFunctionality2
派生功能的每个实际结构中实现。这是低效的实施工作。更糟糕的是:每当
CommonFunctionality
发生变化时,我都必须重新设计所有结构。

rust traits
1个回答
0
投票

没有什么可以阻止新特征或具体类型

FooBar
实现这两个特征
SpecialFunctionality1
SpecialFunctionality2

在这种情况下,编译器应该选择哪个专业化?是因为

FooBar
实现了
...1
而发生的,还是因为
FooBar
实现了
...2

发生的?

这就是错误的来源。

@john-kugelman 已经给出了一些想法:辅助方法和枚举。

您通常可以在枚举和特征之间做出设计决策,这取决于您的类型是否更可能详尽并由您(作为库的作者)或用户控制。

如果我上面提到的情况,即结构实现了这两个特殊功能特征,实际上永远不会发生,那么枚举听起来就很正确。

在其他情况下,获得代码重用的方法是通过

#[derive]
宏,但我没有任何实现该方法的经验。

© www.soinside.com 2019 - 2024. All rights reserved.