向量实现问题

Vector implementation problems

我正在尝试用 Rust 编写一个数学矢量库,但我遇到了一些我真正想解决的问题。我想解决两个问题:

最小工作示例

#[derive(Debug)]
struct Vector<T> {
    elements: [T]
}

// multiple base trait implementations
impl<T> /* … */ for Vector<T> { }


// one of multiple macros
macro_rules! impl_vector_normal_arithmetic {
    ($(impl $trait:ident for Vector { $function:ident($symbol:tt) })+) => {
        $(
            //            ———————— Error: the trait `Sized` is not implemented for `[T]`
            //            vvvvvv
            impl<T : Num> $trait for Vector<T> {
                type Output = Self;
            
                #[inline(always)]
                fn $function(&self, other: Self) -> Self {
                    Self::new(
                        self.iter()
                            .zip(other.iter())
                            .map(|(&lhs, &rhs)| lhs $symbol rhs)
                            .collect()
                    )
                }
            }
        )+
    };
}

impl_vector_normal_arithmetic! {
    impl Add for Vector { add(+) }
    impl Sub for Vector { sub(-) }
    impl Mul for Vector { mul(*) }
    impl Div for Vector { div(/) }
}

Sized 未为 [T] 实现”错误

我的矢量实现包含一个通用矢量定义,理论上,它应该能够包含无限大的矢量。这些向量只能在给定大小后实例化——这意味着使用数组。然后使用宏来添加一些算术特征(Add、Sub、Div、Mul 等)。然而,这会导致一个问题。我无法实现这些功能,因为编译器告诉我 [T] 没有实现 Sized 特性。我明白错误告诉我的是什么,但我知道如何告诉编译器大小是多少并不重要(因为函数不关心)。我该怎么做才能解决此编译器错误?

使Vecor<T>elements变密

我的 Vector<T> 结构包含 / 可以由 [T] 类型的 elements 定义。昨天,我正在阅读一些内存分配,并遇到了稀疏和密集的内存分配。我想知道 Rust 定义的数组是否密集(id est 所有项目在(虚拟)内存中按顺序分配),因为这就是我想要通过这些向量定义实现的。

These vectors can only be instantiated once given a size - which implies the use of the array.

但是你没有写数组;你已经写了一个 slice,这意味着 运行 次大小选择,而不是一般大小选择。 [T] 具有动态大小;因此 Vector<T> 具有动态大小;因此 Vector<T> 不能在堆栈上传递或返回,并且必须始终在某个指针后面处理。这可能不是你想要的。

要声明一个数组,你必须写类型[T; N],而不是[T]

#[derive(Debug)]
struct Vector<T, const N: usize> {
    elements: [T; N]
}

这样,Vector 将永远是 Sized,避免出现您询问的错误。您需要以相同的方式使现有的通用代码在 NT 上通用。例如,这里是 Add:

的实现
impl<T: num_traits::NumAssign, const N: usize> Add for Vector<T, N> {
    type Output = Self;
    fn add(mut self, other: Self) -> Self {
        for (self_el, other_el) in
            self.elements.iter_mut().zip(other.elements.into_iter())
        {
            *self_el += other_el;
        }
        self
    }
}

(它使用循环而不是 .collect(),因为 Iterator::collect() 无法收集到数组中,因为迭代器通常没有静态已知长度。)