在Java语言中,我有一个interface R
,一个interface RT extends R
(其中RT
实现了R
的全部)和一堆其他都实现了{{ 1}}。
向Rust的过渡我有两个特征
RT
其中trait R { ... }
trait RT { ... }
是RT
的“子特征”:
R
接着我有一堆结构,所有结构都实现了impl R for X where X: RT { ... }
:
RT
到目前为止很好。
现在,我希望所有这些结构在实现struct RV { ... }
impl RT for RV { ... }
struct I { ... }
impl RT for I { ... }
struct U { ... }
impl RT for U { ... }
// ...
的基础上彼此具有可比性。
在Java中,我将RT
更改为
RT
并为interface RT extends R, Comparable<RT>
和equals
添加默认实现。
在Rust中,我不知道是否或如何解决这个问题。
我可以说compareTo
,但这只会使一个实现与其自身具有可比性(trait RT: PartialEq
,而不是RV == RV
)。
我的下一个想法是为每个结构添加一揽子实现:
RV == U
我理解为什么不允许这样做,但是我仍然坚持最初的问题。
我无法转换比较值(impl PartialEq<RV> for X where X: RT
impl PartialEq<I> for X where X: RT
// ...
,因为无法将RV as RT == U as RT
制成对象。
我可以为每种结构组合手动实现RT
,但这会造成很多重复。
我考虑过使用宏来生成所有不同的实现,但是感觉就像蛮力的,所以我质疑程序的初始设计。
我如何使所有不同的结构彼此可比?
答案 0 :(得分:1)
这种模式通常出现在Java中,以模拟带标记的联合,这是Java语言所缺少的。在Rust中,除非您编写的库的用户可能需要定义RT
的新实现,否则我怀疑您会更满意使用enum
而不是trait对象:
#[derive(PartialEq, Eq)]
enum AnyRT {
RV(RV),
I(I),
U(U),
}
impl RT for AnyRT {
fn foo(&self, ...) {
match self {
AnyRT::RV(rv) => rv.foo(...),
AnyRT::I(i) => i.foo(...),
AnyRT::U(u) => u.foo(...),
}
}
}
然后,根据您的应用程序,您可能会发现根本不需要RT
特征和/或单独的RV
,I
,U
结构