Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 为自定义特性提供一揽子特性实现_Rust - Fatal编程技术网

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
可以标记为私有的(现在不可能),那么这是可能的。