Rust 为自定义特性提供一揽子特性实现
我正在实现一个用于实践的快速几何板条箱,我想实现两个结构,Rust 为自定义特性提供一揽子特性实现,rust,Rust,我正在实现一个用于实践的快速几何板条箱,我想实现两个结构,向量和法线(这是因为标准向量和法线向量通过不同的变换映射)。我实现了以下特性: trait Components { fn new(x: f32, y: f32, z: f32) -> Self; fn x(&self) -> f32; fn y(&self) -> f32; fn z(&self) -> f32; } 我还想把两个向量和两个法线加在一起,所以我有这样的块:
向量
和法线
(这是因为标准向量和法线向量通过不同的变换映射)。我实现了以下特性:
trait Components {
fn new(x: f32, y: f32, z: f32) -> Self;
fn x(&self) -> f32;
fn y(&self) -> f32;
fn z(&self) -> f32;
}
我还想把两个向量和两个法线加在一起,所以我有这样的块:
impl Add<Vector> for Vector {
type Output = Vector;
fn add(self, rhs: Vector) -> Vector {
Vector { vals: [
self.x() + rhs.x(),
self.y() + rhs.y(),
self.z() + rhs.z()] }
}
}
impl Add<Components> for Components {
type Output = Components;
fn add(self, rhs: Components) -> Components {
Components::new(
self.x() + rhs.x(),
self.y() + rhs.y(),
self.z() + rhs.z())
}
}
impl<T: Components> Add<T> for T {
type Output = T;
fn add(self, rhs: T) -> T {
T::new(
self.x() + rhs.x(),
self.y() + rhs.y(),
self.z() + rhs.z())
}
}
其中“
组件
”将自动被相应类型替换。我想我可以用宏来做,但这对我来说似乎有点不方便。目前,宏是唯一可以做到这一点的方法。一致性规则防止多个可能重叠的实现,因此不能使用通用解决方案。在Rust中,可以定义通用的impl
s,但一致性规则会产生一些重要的限制。您需要一个impl
,如下所示:
impl Add<Vector> for Vector {
type Output = Vector;
fn add(self, rhs: Vector) -> Vector {
Vector { vals: [
self.x() + rhs.x(),
self.y() + rhs.y(),
self.z() + rhs.z()] }
}
}
impl Add<Components> for Components {
type Output = Components;
fn add(self, rhs: Components) -> Components {
Components::new(
self.x() + rhs.x(),
self.y() + rhs.y(),
self.z() + rhs.z())
}
}
impl<T: Components> Add<T> for T {
type Output = T;
fn add(self, rhs: T) -> T {
T::new(
self.x() + rhs.x(),
self.y() + rhs.y(),
self.z() + rhs.z())
}
}
impl为T添加{
类型输出=T;
fn添加(自身,右侧:T)->T{
T::新的(
self.x()+rhs.x(),
self.y()+rhs.y(),
self.z()+rhs.z())
}
}
不幸的是,这并没有编译:
错误:类型参数T
必须用作某些本地类型的类型参数(例如MyStruct
);类型参数[]只能实现当前板条箱中定义的特征
为什么??假设您的组件
特性是公共的。现在,另一个板条箱中的类型可以实现组件
特性。该类型还可能尝试实现Add
特性。您的板条箱或其他板条箱的Add
的实现应该是谁的?根据Rust当前的一致性规则,另一个板条箱获得此特权
目前,除了重复
impl
s之外,唯一的选择是使用宏。Rust的标准库在许多地方使用宏,以避免重复impl
s(特别是对于基本类型),因此您不必感到脏!:P很有趣,谢谢。有没有计划为类似的东西提供支持?我不知道确切的计划,但对我来说,如果特征是私有的(不是从板条箱中导出),或者如果impl
可以标记为私有的(现在不可能),那么这是可能的。