What's the proper approach to compute arithmetic operations on a borrowed vector of elements that lack Copy
in Rust? In the following code, I'd like foo
to borrow a vector x
and then compute a short function. The trick is that the elements in x
necessarily lack the Copy
trait. Anyway, the code
fn foo<Real>(x: &Vec<Real>) -> Real
where
Real: std::ops::Add<Output = Real> + std::ops::Mul<Output = Real> + Clone,
{
(x[0] + x[1]) * x[2]
}
fn main() {
let x = vec![1.2, 2.3, 3.4];
let _y = foo::<f64>(&x);
}
Fails to compile with the error
error[E0507]: cannot move out of index of `std::vec::Vec<Real>`
--> src/main.rs:5:6
|
5 | (x[0] + x[1]) * x[2]
| ^^^^ move occurs because value has type `Real`, which does not implement the `Copy` trait
error[E0507]: cannot move out of index of `std::vec::Vec<Real>`
--> src/main.rs:5:13
|
5 | (x[0] + x[1]) * x[2]
| ^^^^ move occurs because value has type `Real`, which does not implement the `Copy` trait
error[E0507]: cannot move out of index of `std::vec::Vec<Real>`
--> src/main.rs:5:21
|
5 | (x[0] + x[1]) * x[2]
| ^^^^ move occurs because value has type `Real`, which does not implement the `Copy` trait
This makes sense. The indexing attempts to move out borrowed content. That said, if we try to borrow on the indices:
fn foo<Real>(x: &Vec<Real>) -> Real
where
Real: std::ops::Add<Output = Real> + std::ops::Mul<Output = Real> + Clone,
{
(&x[0] + &x[1]) * &x[2]
}
fn main() {
let x = vec![1.2, 2.3, 3.4];
let _y = foo::<f64>(&x);
}
Then, we get a new compiler error:
error[E0369]: binary operation `+` cannot be applied to type `&Real`
--> src/main.rs:5:12
|
5 | (&x[0] + &x[1]) * &x[2]
| ----- ^ ----- &Real
| |
| &Real
|
= note: an implementation of `std::ops::Add` might be missing for `&Real`
This also makes sense; the traits Add
and Mul
are on Real
and not &Real
. Nevertheless, I'm not sure how to resolve the error. Is there a straightforward fix?