Я реализую основные операции c для матриц в поле c F
. При этом я хочу перегрузить оператор добавления для типа матрицы. Тип матрицы содержит Cow
владеющий или заимствующий F
. Я хочу, чтобы полученная сумма матрицы заняла F
добавленной матрицы независимо от того, владеет ли она или занимает F
.
. Компилятор жалуется, что я возвращаю ссылку, созданную внутри функции, но я не понимаю почему. Мне кажется, я ссылаюсь на входной аргумент функции, а не на данные, созданные локально. Вот мой минимальный пример:
use std::{
borrow::{Borrow, Cow},
ops::Add,
};
pub trait Field {
type FElt: Copy + Eq;
fn zero(&self) -> Self::FElt;
fn add(&self, a: Self::FElt, b: Self::FElt) -> Self::FElt;
}
pub struct Mat<'a, F: Clone + Eq + Field> {
field: Cow<'a, F>,
rows: usize,
cols: usize,
data: Vec<F::FElt>,
}
impl<'a, F: Clone + Eq + Field> Mat<'a, F> {
pub fn zero(field: &'a F, rows: usize, cols: usize) -> Self {
if rows == 0 || cols == 0 {
panic!("Empty matrix");
}
Self {
field: Cow::Borrowed(field),
rows,
cols,
data: vec![field.zero(); rows * cols],
}
}
}
impl<'a, F: Clone + Eq + Field> Add for Mat<'a, F> {
type Output = Self;
fn add(self, other: Self) -> Self::Output {
if self.field != other.field {
panic!("Cannot add matrices: fields do not match");
}
if self.rows != other.rows || self.cols != other.cols {
panic!("Cannot add matrices: dimensions do not match");
}
let f: &F = self.field.borrow();
let mut sum = Mat::zero(f, self.rows, self.cols);
for i in 0..self.rows * self.cols {
sum.data[i] = f.add(self.data[i], other.data[i]);
}
sum
}
}
fn main() {}
Вот ошибка, которую я получаю:
error[E0515]: cannot return value referencing local data `self.field`
--> src/main.rs:51:9
|
46 | let f: &F = self.field.borrow();
| ---------- `self.field` is borrowed here
...
51 | sum
| ^^^ returns a value referencing data owned by the current function