如何在Rust中共享功能?

如何在Rust中共享功能?,rust,Rust,现在,我想创建一个Normal,它的行为几乎与向量完全相同,但我需要区分类型。例如,变换法线不同于变换向量。例如,您需要使用变换(逆)矩阵对其进行变换 现在我可以这样做: struct Vector { data: [f32; 2] } impl Vector { //many methods } 然后重新实现所有功能 struct Normal { v: Vector } 我想我也可以用它 不确定如何实现子范围的功能。例如,点积可能仅适用于法线和向量,而不适用于点

现在,我想创建一个
Normal
,它的行为几乎与
向量
完全相同,但我需要区分类型。例如,变换法线不同于变换向量。例如,您需要使用变换(逆)矩阵对其进行变换

现在我可以这样做:

struct Vector {
    data: [f32; 2]
}

impl Vector {
   //many methods
}
然后重新实现所有功能

struct Normal {
    v: Vector
}
我想我也可以用它

不确定如何实现子范围的功能。例如,点积可能仅适用于法线和向量,而不适用于点

是否可以表示特征边界的布尔表达式

impl Vector<NormalType> {..} // Normal specific stuff
trait-NormalTrait;
性状向量;
NormalType{}的impl NormalTrait
向量类型{}的impl vectorrait
向量的impl{
fn点(自身,其他:向量)->f32{..}
}

我的备选方案是什么?

你的问题相当广泛,涉及很多话题。但是您的
PhantomData
想法可能是一个很好的解决方案。您可以为不同的泛型类型编写不同的
impl
块。我在代码中添加了一些内容:

trait NormalTrait;
trait VectorTrait;
impl NormalTrait for NormalType {}
impl VectorTrait for VectorType {}

impl<T: PointTrait or VectorTrait> for Vector<T> {
    fn dot(self, other: Vector<T>) -> f32 {..} 
}
struct向量类型;
结构规范类型;
结构点类型;
结构向量{
数据:[f32;2],
_类型:幻影数据,
}
类型法线=向量;
类型点=向量;
//---这一行上面是旧代码--------------------
特征点{}
向量类型{}的impl Pointy
点类型{}的impl Pointy
//实现所有向量类型
impl向量{
fn new()->Self{
载体{
数据:[0.0,0.0],
_类型:幻影数据,
}
}
}
//“尖头”向量类型的impl
impl向量{
fn add(&mut self,other:Vector){}
fn变换(&mut self){/*标准矩阵乘法*/}
}
//法线的impl
impl向量{
fn变换(&mut-self){/*变换逆矩阵stuff*/}
}
fn main(){
设mut n=Normal::new();
设mut p=Point::new();
n、 transform();
p、 transform();
//n.add(Normal::new());//错误:
//在当前作用域中找不到类型为“Vector”的名为“add”的方法
p、 添加(Point::new());
}
是否可以表示特征边界的布尔表达式

impl Vector<NormalType> {..} // Normal specific stuff

没有(还没有)。但在这种情况下,您可以如上所示解决它:您创建一个新的trait(
Pointy
),并为“or”-条件中的类型实现它。然后你就被这种特质束缚住了。

不需要
幻影数据。只要用
T
(我想)替换它就行了。类似于字节顺序是如何实现的。特征边界中的布尔表达式是否有RFC?@MaikKlein与所讨论的情况不完全相同,但我的答案无论如何会有很大变化。@Shepmaster不使用
PhantomData
我们必须构造
T
类型的对象,这有点问题。。。所以我们必须绑定
T:Default
或任何东西。我想:P
trait NormalTrait;
trait VectorTrait;
impl NormalTrait for NormalType {}
impl VectorTrait for VectorType {}

impl<T: PointTrait or VectorTrait> for Vector<T> {
    fn dot(self, other: Vector<T>) -> f32 {..} 
}
struct VectorType;
struct NormalType;
struct PointType;
struct Vector<T = VectorType> {
    data: [f32; 2],
    _type: PhantomData<T>,
}
type Normal = Vector<NormalType>;
type Point = Vector<PointType>;

// --- above this line is old code --------------------

trait Pointy {}
impl Pointy for VectorType {}
impl Pointy for PointType {}

// implement for all vector types
impl<T> Vector<T> {
    fn new() -> Self {
        Vector {
            data: [0.0, 0.0],
            _type: PhantomData,
        }
    }
}

// impl for 'pointy' vector types
impl<T: Pointy> Vector<T> {
    fn add<R>(&mut self, other: Vector<R>) {}
    fn transform(&mut self) { /* standard matrix multiplication */ }
}

// impl for normals
impl Vector<NormalType> {
    fn transform(&mut self) { /* tranposed inversed matrix stuff */ }
}

fn main() {
    let mut n = Normal::new();
    let mut p = Point::new();
    n.transform();
    p.transform();

    // n.add(Normal::new());  // ERROR:
    // no method named `add` found for type `Vector<NormalType>` in the current scope
    p.add(Point::new());
}