当使用具有运算符重载的类时,我从简单的辅助方法获得编译错误.这是一个独立的测试(从我的真实代码简化,但仍然证明了问题):
use std::ops::{Add, Sub, Neg, Mul, Div};
#[derive(Debug, Eq, PartialEq)]
pub struct Money {
cents: i64,
}
impl Money {
pub fn new(cents: i64) -> Money {
Money { cents: cents }
}
}
impl Add for Money {
type Output = Money;
fn add(self, other: Money) -> Money {
Money { cents: self.cents + other.cents }
}
}
impl Mul<Money> for f64 {
type Output = Money;
fn mul(self, rhs: Money) -> Money {
Money { cents: (self * rhs.cents as f64) as i64 }
}
}
#[derive(Debug)]
pub struct AbsOrPerc {
pub absolute: Money,
pub percent: f64,
}
impl AbsOrPerc {
pub fn new(abs: Money, perc: f64) -> AbsOrPerc {
AbsOrPerc {
absolute: abs,
percent: perc,
}
}
pub fn total(&self, basis: Money) -> Money {
// This works:
// Money::new((self.absolute.cents as f64 + self.percent * basis.cents as f64) as i64)
// This doesn't:
self.absolute + self.percent * basis
}
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用Rust 1.8编译它,但我收到此错误:
src/lib.rs:42:5: 42:9 error: cannot move out of borrowed content [E0507]
src/lib.rs:42 self.absolute + self.percent * basis
Run Code Online (Sandbox Code Playgroud)
我已经阅读了Rust Book,以及关于所有权和借来的部分.我在StackOverflow上已经阅读了很多关于这个问题的问题,例如:
我不认为我自己的问题是重复的,因为虽然错误是相同的,但情况是不同的.此外,如果我知道其他问题是如何适用于这个问题,我也不必问.:-)
所以我的问题是:我该如何解决这个错误?我并不想改变&self到self,因为这会导致其他问题.
除了解决问题之外,我还想知道Rust害怕什么.我没有看到任何危险.
你是在实现运营商Money而不是&Money.这意味着运营商将获得其操作数的所有权.因此,在total执行添加时,您必须移动self.absolute,这是不允许的,因为您无法移出借来的指针(您只能移动您拥有的值).如果类型实现,Rust将复制值Copy(对于诸如i32或的原语就是这种情况f64); 否则,它会移动它们,这意味着移动后源将无法使用.
如果你的Money结构实际上只包含一个cents字段,我建议你实现它Copy(这也需要实现Clone,即使你没有实现,这也是一个好主意Copy).您可以实现Copy和Clone使用容易#[derive]:
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct Money {
cents: i64,
}
Run Code Online (Sandbox Code Playgroud)
现在,Rust不会total移动self.absolute,而是会复制它.如果无法实现Copy,则替换self.absolute为self.absolute.clone().
如果您已经实现了运算符&Money,那么您可以只传递对Money值的引用.例如,使用这样的实现,total可以像这样实现:
pub fn total(&self, basis: Money) -> Money {
&self.absolute + &(self.percent * &basis)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
669 次 |
| 最近记录: |