rust - 如何在 Rust 中共享功能?

标签 rust

struct Vector {
    data: [f32; 2]
}

impl Vector {
   //many methods
}

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

现在我可以这样做:

struct Normal {
    v: Vector
}

然后重新实现所有的功能

impl Normal {
    fn dot(self, other: Normal) -> f32 {
        Vector::dot(self.v, other.v)
    }
    ....
}

我想我也可以用 PhantomData 来做

struct VectorType;
struct NormalType;
struct PointType;
struct Vector<T = VectorType> {
    data: [f32; 2],
    _type: PhantomData<T>,
}
type Normal = Vector<NormalType>;

但是我还需要一种方法来实现特定类型的功能。

它应该很容易实现,例如 add 可以为所有内容添加 point + vector

或特定于某种类型的功能

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

不确定我将如何实现子范围的功能。例如,点积可能只对法线和向量有意义,但对点没有意义。

是否可以为特征边界表达 bool 表达式?

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 {..} 
}

我有什么选择?

最佳答案

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

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());
}

Is it possible to express boolean expression for trait bounds?

没有(还没有)。但是在这种情况下您可以解决它,如上所示:您创建一个新特征 (Pointy) 并为您的“或”条件中的类型实现它。然后你就绑定(bind)了那个特性。

关于rust - 如何在 Rust 中共享功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38185385/

相关文章:

Rust 对特征实现的自动类型推断

rust - 从闭包发送 channel 信号

rust - 我如何强制执行父子结构生命周期?

c++ - 编译为 wasm 的 C++ 和 Rust 程序能否以某种方式互操作?

rust - 不能对数组的大小使用惰性静态整数常量

rust - Rust PathBuf 如何防止目录遍历攻击?

visual-studio-code - 如何获取要显示的类型提示?

rust - 如何从主泛型推论出子泛型?

rust - 结果没有名为 "unwrap()"的方法?

string - 如何将带有多个参数的单个字符串传递给 std::process::Command?