如何在元素的借用向量上计算算术运算,这些元素在Rust中没有副本?

如何在元素的借用向量上计算算术运算,这些元素在Rust中没有副本?,rust,Rust,在Rust中缺少Copy的元素的借用向量上计算算术运算的正确方法是什么?在下面的代码中,我希望foo借用一个向量x,然后计算一个短函数。诀窍在于x中的元素必然缺少Copy特性。不管怎样,代码 fn foo(x:&Vec)->Real 哪里 Real:std::ops::Add+std::ops::Mul+Clone, { (x[0]+x[1])*x[2] } fn main(){ 设x=vec![1.2,2.3,3.4]; 设y=foo::(&x); } 未能编译,出现错误 错误[E0507]

在Rust中缺少
Copy
的元素的借用向量上计算算术运算的正确方法是什么?在下面的代码中,我希望
foo
借用一个向量
x
,然后计算一个短函数。诀窍在于
x
中的元素必然缺少
Copy
特性。不管怎样,代码

fn foo(x:&Vec)->Real
哪里
Real:std::ops::Add+std::ops::Mul+Clone,
{
(x[0]+x[1])*x[2]
}
fn main(){
设x=vec![1.2,2.3,3.4];
设y=foo::(&x);
}
未能编译,出现错误

错误[E0507]:无法移出'std::vec::vec'的索引`
-->src/main.rs:5:6
|
5 |(x[0]+x[1])*x[2]
|^^^^发生移动是因为值的类型为'Real',该类型未实现'Copy'特性
错误[E0507]:无法移出'std::vec::vec'的索引`
-->src/main.rs:5:13
|
5 |(x[0]+x[1])*x[2]
|^^^^发生移动是因为值的类型为'Real',该类型未实现'Copy'特性
错误[E0507]:无法移出'std::vec::vec'的索引`
-->src/main.rs:5:21
|
5 |(x[0]+x[1])*x[2]
|^^^^发生移动是因为值的类型为'Real',该类型未实现'Copy'特性
这是有道理的。索引尝试移出借用的内容。也就是说,如果我们试图借用指数:

fn foo(x:&Vec)->Real
哪里
Real:std::ops::Add+std::ops::Mul+Clone,
{
(&x[0]+&x[1])*&x[2]
}
fn main(){
设x=vec![1.2,2.3,3.4];
设y=foo::(&x);
}
然后,我们得到一个新的编译器错误:

error[E0369]:二进制操作“+”不能应用于类型“%Real”`
-->src/main.rs:5:12
|
5 |(&x[0]+&x[1])*&x[2]
|-----^-----&Real
|      |
|&真实
|
=注意:`&Real可能缺少`std::ops::Add`的实现`

这也是有道理的;traits
Add
Mul
Real
上,而不是
&Real
上。然而,我不知道如何解决这个错误。有一个简单的解决方法吗?

你只需要使用奥术魔法召唤,一旦你学会了这种力量,你只需要使用它:

fn foo(x:&[Real])->Real
哪里
用于
符号

见:


你只需要使用奥术魔法召唤,一旦你学会了这种力量,你只需要使用它:

fn foo(x:&[Real])->Real
哪里
用于
符号

见:


如果您只需要
Real
来实现
Add
,那么您必须同时使用
Real
来添加它们。如果要添加而不使用,则需要为
&Real
要求
添加

或者,您已经为
Real
添加了trait绑定的
Clone
,这意味着您可以在添加
Real
之前克隆它们

use std::ops::{Add, Mul};

// You shouldn't ever use the type &Vec<T> as an input,
// since it's unnecessarily restrictive and introduces two layers of indirection
fn foo_clone<Real>(x: &[Real]) -> Real
where
    Real: Add<Output = Real> + Mul<Output = Real> + Clone,
{
    (x[0].clone() + x[1].clone()) * x[2].clone()
}

// This uses the higher-ranked trait bounds that Stargateur mentioned
// It basically means that the implementation of `Add` for `Real`
// can't restrict the lifetime.
fn foo_ref_add<Real>(x: &[Real]) -> Real
where
    for <'a> &'a Real: Add<Output = Real> + Mul<Output = Real>,
{
    &(&x[0] + &x[1]) * &x[2]
}

fn main() {
    let x = vec![1.2, 2.3, 3.4];
    let _y = foo_clone::<f64>(&x);
    let _z = foo_ref_add::<f64>(&x);
}
使用std::ops:{Add,Mul};
//您不应该使用type&Vec作为输入,
//因为它具有不必要的限制性,并且引入了两层间接寻址
fn foo_clone(x:&[Real])->Real
哪里
Real:Add+Mul+Clone,
{
(x[0]。克隆()+x[1]。克隆())*x[2]。克隆()
}
//这使用了Stargateur提到的更高等级的特征界限
//它基本上意味着“添加”的实现是“真实的”`
//不能限制生命。
fn foo_ref_add(x:&[Real])->Real
哪里

对于来说,如果您只需要
Real
来实现
Add
,那么您必须同时使用
Real
来添加它们。如果要添加而不使用,则需要为
&Real
要求
添加

或者,您已经为
Real
添加了trait绑定的
Clone
,这意味着您可以在添加
Real
之前克隆它们

use std::ops::{Add, Mul};

// You shouldn't ever use the type &Vec<T> as an input,
// since it's unnecessarily restrictive and introduces two layers of indirection
fn foo_clone<Real>(x: &[Real]) -> Real
where
    Real: Add<Output = Real> + Mul<Output = Real> + Clone,
{
    (x[0].clone() + x[1].clone()) * x[2].clone()
}

// This uses the higher-ranked trait bounds that Stargateur mentioned
// It basically means that the implementation of `Add` for `Real`
// can't restrict the lifetime.
fn foo_ref_add<Real>(x: &[Real]) -> Real
where
    for <'a> &'a Real: Add<Output = Real> + Mul<Output = Real>,
{
    &(&x[0] + &x[1]) * &x[2]
}

fn main() {
    let x = vec![1.2, 2.3, 3.4];
    let _y = foo_clone::<f64>(&x);
    let _z = foo_ref_add::<f64>(&x);
}
使用std::ops:{Add,Mul};
//您不应该使用type&Vec作为输入,
//因为它具有不必要的限制性,并且引入了两层间接寻址
fn foo_clone(x:&[Real])->Real
哪里
Real:Add+Mul+Clone,
{
(x[0]。克隆()+x[1]。克隆())*x[2]。克隆()
}
//这使用了Stargateur提到的更高等级的特征界限
//它基本上意味着“添加”的实现是“真实的”`
//不能限制生命。
fn foo_ref_add(x:&[Real])->Real
哪里
对于可能重复的,可能重复的