I am writing a struct named Operator
that calculates and accumulates input structs.
Add
and Mul
operators are implemented for the input struct:
use std::ops::Add;
use std::ops::Mul;
struct MyInt {
val: u32,
}
impl Add<&MyInt> for &MyInt {
type Output = MyInt;
fn add(self, rhs: &MyInt) -> Self::Output {
MyInt {
val: self.val + rhs.val,
}
}
}
impl Mul<&MyInt> for &MyInt {
type Output = MyInt;
fn mul(self, rhs: &MyInt) -> Self::Output {
MyInt {
val: self.val * rhs.val,
}
}
}
struct Operator {
x: MyInt,
}
impl Operator {
fn step(&mut self, x: &MyInt) {
self.x = &self.x + x;
self.x = &self.x * x;
}
}
fn main() {
let mut operator = Operator {
x: MyInt { val: 0 },
};
for i in 0..10 {
let i = MyInt { val: i };
operator.step(&i);
}
println!("{}", operator.x.val);
}
The above code works fine.
Next, I replaced Operator
with generics code. It takes a type parameter T
instead of MyInt
.
I put some explicit lifetimes to solve some compile errors:
struct Operator2<T> {
x: T,
}
impl<'a, 'b, T> Operator2<T>
where
&'a T: 'a + 'b + Add<&'b T, Output = T> + Mul<&'b T, Output = T>,
{
fn step(&'a mut self, x: &'b T) {
self.x = &self.x + x;
self.x = &self.x * x;
}
}
It does not work:
error[E0506]: cannot assign to `self.x` because it is borrowed
--> src/main.rs:47:9
|
42 | impl<'a, 'b, T> Operator2<T>
| -- lifetime `'a` defined here
...
47 | self.x = &self.x + x;
| ^^^^^^ -------
| | |
| | borrow of `self.x` occurs here
| | requires that `self.x` is borrowed for `'a`
| assignment to borrowed `self.x` occurs here
error[E0506]: cannot assign to `self.x` because it is borrowed
--> src/main.rs:48:9
|
42 | impl<'a, 'b, T> Operator2<T>
| -- lifetime `'a` defined here
...
47 | self.x = &self.x + x;
| -------
| |
| borrow of `self.x` occurs here
| requires that `self.x` is borrowed for `'a`
48 | self.x = &self.x * x;
| ^^^^^^ assignment to borrowed `self.x` occurs here
How to fix the above generics code?