Matrix Rust traits:边界可能没有实现,traits I';您所实现的功能不存在

Matrix Rust traits:边界可能没有实现,traits I';您所实现的功能不存在,matrix,vector,rust,traits,bounds,Matrix,Vector,Rust,Traits,Bounds,所以我一直在尝试实现一个向量和矩阵数学库,我创建了一些函数,这些函数可以正常工作,但希望对所有数字原语进行推广,并将这些函数添加到普通运算符中 我的想法是为Vec创建一个容器,它可以包含数字类型(如i32)或另一个Vec容器,以便在可能的情况下使用矩阵。因此: #[derive(Clone, Debug)] struct Mat<T>(Vec<T>); 但是矩阵让我头疼。对于他们来说,add函数看起来非常相似,除了let Some(x)语句: impl<'a, T

所以我一直在尝试实现一个向量和矩阵数学库,我创建了一些函数,这些函数可以正常工作,但希望对所有数字原语进行推广,并将这些函数添加到普通运算符中

我的想法是为
Vec
创建一个容器,它可以包含数字类型(如
i32
)或另一个
Vec
容器,以便在可能的情况下使用矩阵。因此:

#[derive(Clone, Debug)]
struct Mat<T>(Vec<T>);
但是矩阵让我头疼。对于他们来说,add函数看起来非常相似,除了
let Some(x)
语句:

impl<'a, T> Add for &'a Mat<Mat<T>>
where T: Add<&'a Mat<T>>{
    type Output = Option<Mat<T>>;

    fn add(self, other: &Mat<Mat<T>>) -> Self::Output {
        let a: &Vec<Mat<T>> = self.pop();
        let b: &Vec<Mat<T>> = other.pop();
        match a.len() == b.len() {
            true => {
                let mut retvec: Vec<T> = Vec::new();
                for i in 0..a.len() {
                    if let Some(x) = &a[i] + &b[i] {
                        retvec.push(x);
                    }
                }
                Some(Mat(retvec))
            },
            false => None
        }
    }
}

impl有两个问题:错误关联的
Output
类型和
retvec

类似的方法应该会奏效:

impl<'a, T> Add for &'a Mat<Mat<T>>
where
    T: PartialEq + PartialOrd + Add<T> + Clone,
{
    type Output = Option<Mat<Mat<<T as std::ops::Add>::Output>>>;

    fn add(self, other: &Mat<Mat<T>>) -> Self::Output {
        let a: &Vec<Mat<T>> = self.pop();
        let b: &Vec<Mat<T>> = other.pop();
        match a.len() == b.len() {
            true => {
                let mut retvec: Vec<Mat<<T as std::ops::Add>::Output>> = Vec::new();
                for i in 0..a.len() {
                    if let Some(x) = &a[i] + &b[i] {
                        retvec.push(x);
                    }
                }
                Some(Mat(retvec))
            }
            false => None,
        }
    }
}
对于
Mat
值的附加impl:

impl<T> Add for Mat<T>
where
    T: PartialEq + PartialOrd + Add<T> + Clone

PS:Your
Mat
类型不是经典意义上的矩阵,也许另一个名称更合适,以避免混淆。

可能重复的Hmm,我想我误读了。您的意思是要将
T
添加到实现内部的
Mat
中吗?这就是
T:for
的含义。我怀疑你真的想要
,因为我不确定我是否得到了你想要的,如果你的意思是我忘了为
T
Mat
实现一个Add函数,那么我想我不需要,因为forloop在两个函数中都通过两个向量循环,它只需要添加
T+T
Mat+Mat
,对吗?否则,如果您的意思是如果我尝试执行
T+Mat
,那么不,我发布的测试是到目前为止唯一的测试。您的
where
子句适用于
T+&Mat
,但您在函数内部实际执行的是
&Mat+&Mat
(我认为)。但这并不是全部,因为修复绑定会导致其他问题。我认为,您需要的不是
&a[I]+&b[I]
,而是
a[I].clone()+b[I].clone()
编辑:不,愚蠢的我。忘记推导PartialEq和PartialOrd。正如我所说,非常感谢!顺便说一句,这怎么不好?我把它们描述成向量的向量。谢谢,伙计,解释得好!是的,我同意
Mat
在概念上很弱,但我只是在与编译器抗争。即使现在我已经复制了你的代码,如果我把
Mat
测试留在里面,它也不会编译。仍然是同样的错误:“对于
Mat
,可能缺少
std::ops::Add
的实现”,而你说它对你有效,这让我怀疑存在的逻辑和原因。通常,矩阵被定义为多维数组,每个维度的基数相同。使用
Mat
类型,您可以有不同大小的行。对,但它实际上无法计算那些格式错误的矩阵。您建议如何解决这个问题,一个宏或者一个使其符合正确向量维度的
Mat::new()
成员函数?
impl<'a, T> Add for &'a Mat<Mat<T>>
where
    T: PartialEq + PartialOrd + Add<T> + Clone,
{
    type Output = Option<Mat<Mat<<T as std::ops::Add>::Output>>>;

    fn add(self, other: &Mat<Mat<T>>) -> Self::Output {
        let a: &Vec<Mat<T>> = self.pop();
        let b: &Vec<Mat<T>> = other.pop();
        match a.len() == b.len() {
            true => {
                let mut retvec: Vec<Mat<<T as std::ops::Add>::Output>> = Vec::new();
                for i in 0..a.len() {
                    if let Some(x) = &a[i] + &b[i] {
                        retvec.push(x);
                    }
                }
                Some(Mat(retvec))
            }
            false => None,
        }
    }
}
impl<'a, T> Add for &'a Mat<T>
where
    T: PartialEq + PartialOrd + Add<T> + Clone
impl<T> Add for Mat<T>
where
    T: PartialEq + PartialOrd + Add<T> + Clone
use std::ops::*;
use std::vec::Vec;

#[derive(Clone, Debug, PartialEq, PartialOrd)]
struct Mat<T>(Vec<T>);

impl<T> Mat<T> {
    fn pop(&self) -> &Vec<T> {
        &self.0
    }
}

impl<T> Add for Mat<T>
where
    T: PartialEq + PartialOrd + Add<T> + Clone,
{
    type Output = Mat<<T as std::ops::Add>::Output>;

    fn add(self, other: Mat<T>) -> Self::Output {
        let a: &Vec<T> = self.pop();
        let b: &Vec<T> = other.pop();
        match a.len() == b.len() {
            true => {
                let mut retvec: Vec<<T as std::ops::Add>::Output> = Vec::new();
                for i in 0..a.len() {
                    retvec.push(a[i].clone() + b[i].clone());
                }
                Mat(retvec)
            }
            false => Mat(Vec::new()),
        }
    }
}

impl<'a, T> Add for &'a Mat<T>
where
    T: PartialEq + PartialOrd + Add<T> + Clone,
{
    type Output = Mat<<T as std::ops::Add>::Output>;

    fn add(self, other: &Mat<T>) -> Self::Output {
        let a: &Vec<T> = self.pop();
        let b: &Vec<T> = other.pop();
        match a.len() == b.len() {
            true => {
                let mut retvec: Vec<<T as std::ops::Add>::Output> = Vec::new();
                for i in 0..a.len() {
                    retvec.push(a[i].clone() + b[i].clone());
                }
                Mat(retvec)
            }
            false => Mat(Vec::new()),
        }
    }
}


#[test]
fn add_override_vectors() {
    let vec: Mat<Mat<i32>> = Mat(vec![Mat(vec![2, 2, 2]), Mat(vec![3, 3, 3])]);
    let newvec = &vec + &vec;

    assert_eq!(*newvec.pop(), vec![Mat(vec![4, 4, 4]), Mat(vec![6, 6, 6])]);
}

#[test]
fn add_wrong_vectors() {
    let vec1: Mat<Mat<i32>> = Mat(vec![Mat(vec![2, 2, 2]), Mat(vec![4, 4, 4])]);
    let vec2: Mat<Mat<i32>> = Mat(vec![Mat(vec![3, 3, 3]), Mat(vec![3, 3])]);
    let newvec = &vec1 + &vec2;

    assert_eq!(*newvec.pop(), vec![Mat(vec![5, 5, 5]), Mat(vec![])]);
}


fn main() {
    let vec: Mat<Mat<i32>> = Mat(vec![Mat(vec![1, 2, 2]), Mat(vec![3, 3, 3])]);
    let newvec = &vec + &vec;

    println!("Hello, world!: {:?}", newvec);
}