如何在Rust中缺少Copy的元素的借入向量上计算算术运算?

wye*_*r33 1 rust

Copy在Rust 中缺少的元素的借入向量上计算算术运算的正确方法是什么?在下面的代码中,我想foo借用一个向量x,然后计算一个短函数。诀窍在于元素中x必然缺少Copy特质。无论如何,代码

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);
}
Run Code Online (Sandbox Code Playgroud)

无法编译错误

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
Run Code Online (Sandbox Code Playgroud)

这很有道理。索引尝试移出借用的内容。也就是说,如果我们尝试借入指数:

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);
}
Run Code Online (Sandbox Code Playgroud)

然后,我们得到一个新的编译器错误:

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`
Run Code Online (Sandbox Code Playgroud)

这也是有道理的;特点AddMul存在Real而不是&Real。但是,我不确定如何解决该错误。有直接的解决方法吗?

Sta*_*eur 6

您只需要使用奥术魔法调用“高级特质范围”,一旦学习了此功能,就只需使用它:

fn foo<Real>(x: &[Real]) -> Real
where
    for<'a> &'a Real: std::ops::Add<Output = Real> + std::ops::Mul<Output = Real>,
{
    &(&x[0] + &x[1]) * &x[2]
}

fn main() {
    let x = vec![1.2, 2.3, 3.4];
    let _y = foo::<f64>(&x);
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我们只需要询问&Read工具AddMul但是我们需要某种通用寿命,因此我们使用for<'a>符号。

看到: