简体   繁体   English

Rust:向量实现问题

[英]Rust: vector implementation problems

I'm trying to write a mathematical vector library in rust, but I've encountered some problems I really want to solve.我正在尝试用 rust 编写一个数学向量库,但是我遇到了一些我很想解决的问题。 There are two issues I want to address:我想解决两个问题:

  • the “ Sized is not implemented for [T] ” error [T]未实现Sized ”错误
  • making the element of Vecor<T> dense使Vecor<T>element密集

Minimal working example最小工作示例

#[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(/) }
}

the “ Sized is not implemented for [T] ” error [T]未实现Sized ”错误

My implementation of a vector consists of a generic vector definition that, theoretically, should be able to contain infinitely large vectors.我对向量的实现由一个通用向量定义组成,理论上,该定义应该能够包含无限大的向量。 These vectors can only be instantiated once given a size - which implies the use of the array.这些向量只能在给定大小后实例化 - 这意味着使用数组。 A macro is then used to add some arithmetic features (Add, Sub, Div, Mul, et cetera).然后使用宏来添加一些算术特征(Add、Sub、Div、Mul 等)。 Yet, this causes a problem.然而,这会导致一个问题。 I cannot implement those functions, because the compiler tells me that [T] does not implement the Sized trait.我无法实现这些函数,因为编译器告诉我[T]没有实现Sized特征。 I do understand what the error tells me, but I do know how to tell the compiler that it doesn't matter what the size is (because the function doesn't care).我确实理解错误告诉我什么,但我知道如何告诉编译器大小无关紧要(因为函数不在乎)。 What can I do to get around this compiler error?我该怎么做才能解决这个编译器错误?

making the elements of Vecor<T> dense使Vecor<T>elements密集

My Vector<T> struct contains / can be defined by elements of type [T] .我的Vector<T>结构包含 / 可以由[T]类型的elements定义。 Yesterday, I was reading up on some memory allocation and came across sparse and dense memory allocation.昨天,我正在阅读一些内存分配,并遇到了稀疏和密集的内存分配。 I was wondering if the array defined by Rust is dense (id est all items are allocated in sequential in (virtual) memory), because that's what I want to achieve with these vector definitions.我想知道由 Rust 定义的数组是否是密集的(id est 所有项目在(虚拟)内存中按顺序分配),因为这就是我想要通过这些向量定义实现的目标。

These vectors can only be instantiated once given a size - which implies the use of the array.这些向量只能在给定大小后实例化 - 这意味着使用数组。

But you have not written an array;但是你还没有写数组; you have written a slice , which means run-time choice of size, not generic choice of size.您已经编写了一个slice ,这意味着运行时选择的大小,而不是一般的大小选择。 [T] has a dynamic size; [T]具有动态大小; therefore Vector<T> has a dynamic size;因此Vector<T>具有动态大小; therefore Vector<T> cannot be passed or returned on the stack, and must always be handled behind some pointer.因此Vector<T>不能在堆栈上传递或返回,并且必须始终在某个指针之后进行处理。 This is probably not what you want.这可能不是您想要的。

To declare an array, you must write the type [T; N]要声明一个数组,您必须编写类型[T; N] [T; N] , not [T] . [T; N] ,而不是[T]

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

This way, Vector will always be Sized , avoiding the error you asked about.这样, Vector将始终为Sized ,避免您询问的错误。 You will need to make your existing generic code generic over N as well as T in the same way.您需要以相同的方式使现有的通用代码在NT通用。 For example, here is an implementation of Add :例如,这是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
    }
}

(It uses a loop instead of .collect() because Iterator::collect() can't collect into an array, since iterators in general don't have a statically known length.) (它使用循环而不是.collect()因为Iterator::collect()不能收集到数组中,因为迭代器通常没有静态已知的长度。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM