user124784
user124784

Reputation: 956

Moving collection out of context

I'm trying to implement some traits using life times but as per usual I'm fighting the borrow checker.

My trait looks like this:

pub struct Matrix<T> {
    pub cols: usize,
    pub rows: usize,
    pub data: Vec<T>
}

impl<'a, 'b, T: Copy + Mul<T, Output=T>> Mul<&'b T> for &'a Matrix<T> {
    type Output = Matrix<T>;

    fn mul(self, f: &T) -> Matrix<T> {
        let new_data : Vec<T> = self.data.into_iter().map(|v| v * (*f)).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

Playground link

This gives the following error:

error: cannot move out of borrowed content

I think I understand why this is happening: I am borrowing self and so I can't copy the data. How do I get around this?

Upvotes: 1

Views: 97

Answers (1)

Vladimir Matveev
Vladimir Matveev

Reputation: 127961

This happens because you are using into_iter() on the vector. Since you have Copy bound on T, this is unnecessary; you can use just iter() and dereference the argument in the closure:

pub struct Matrix<T> {
    pub cols: usize,
    pub rows: usize,
    pub data: Vec<T>
}

impl<'a, 'b, T: Copy + Mul<T, Output=T>> Mul<&'b T> for &'a Matrix<T> {
    type Output = Matrix<T>;

    fn mul(self, f: &T) -> Matrix<T> {
        let new_data: Vec<T> = self.data.iter().map(|v| *v * *f).collect();

        Matrix {
            cols: self.cols,
            rows: self.rows,
            data: new_data
        }
    }
}

(playground)

Upvotes: 3

Related Questions