0

I'd like to write an Add operation supported Vector struct, and write a some trait that uses the Vector struct, so I wrote this.

use std::ops::*;
#[derive(Clone)]
struct Vector<T>(Vec<T>);

impl<'a, T> Add<&'a Vector<T>> for Vector<T>
where
    T: AddAssign<&'a T>,
{
    type Output = Vector<T>;
    fn add(mut self, rhs: &'a Vector<T>) -> Self::Output {
        self.0
            .iter_mut()
            .zip(rhs.0.iter())
            .for_each(|(left, right)| {
                *left += right;
            });
        self
    }
}

trait SomeOperation<'a ,T>
where
    T: AddAssign<&'a T>+Clone + 'a,
{
    fn add(u:Vector<T>,v:&'a Vector<T>)->Vector<T>{
        let w = u+v;
        let x = v.clone()+&w;
        x
    }
}

But compilation error occurs.

21 | trait SomeOperation<'a ,T>
   |                     -- lifetime `'a` defined here
...
27 |         let x = v.clone()+&w;
   |                           ^^
   |                           |
   |                           borrowed value does not live long enough
   |                           requires that `w` is borrowed for `'a`
28 |         x
29 |     }
   |     - `w` dropped here while still borrowed

How can I avoid these types of error.

T.Shin
  • 103
  • 7
  • [Here's one way to apply the linked answer to your problem](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=10a7bb4d6e2020f558f99cdabadea8ae). – trent May 23 '20 at 17:21

1 Answers1

0

You talk about implementing AddAssign but your code tries to implement Add. Also, I couldn't figure out what SomeOperation was for. I added the Debug trait to the derive line.

use std::ops::*;
#[derive(Clone, Debug)]
struct Vector<T>(Vec<T>);

impl<'a, T> AddAssign<&'a Vector<T>> for Vector<T>
where
    T: AddAssign<&'a T>
{
    fn add_assign(&mut self, rhs: &'a Vector<T>) {
        self.0
            .iter_mut()
            .zip(rhs.0.iter())
            .for_each(|(left, right)| {
                *left += right;
            });
    }
}
impl<'a, 'b, T> Add<& 'b Vector<T>> for & 'a Vector<T>
where
    Vector<T>: AddAssign<& 'b Vector<T>>,
    T: Clone,
{
    type Output = Vector<T>;
    fn add(self, other: & 'b Vector<T>) -> Self::Output {
        let mut res: Vector<T> = self.clone();
        res += other;
        res
    }
}

fn main() {
    let mut v1: Vector<u32> = Vector(vec![1, 2, 3]);
    let v2 = Vector(vec![4, 5, 6]);
    println!("Add:     {:?}", &v1 + &v2);
    v1 += &v2;
    println!("AddAssign{:?}", v1);
}
NovaDenizen
  • 5,089
  • 14
  • 28
  • I'd like to use a class that support add and add assign in trait. What I show is only a simple example of it. And right hand side of add or add assign operation should be reference because copy or clone on T may be a big cost. – T.Shin May 23 '20 at 05:09