gpt4 book ai didi

rust - "cannot move out of borrowed content"运算符重载

转载 作者:行者123 更新时间:2023-11-29 07:45:30 25 4
gpt4 key购买 nike

当使用带有运算符重载的类时,我从一个简单的辅助方法中得到了一个编译错误。这是一个独立的测试(从我的真实代码中简化而来,但仍然证明了问题所在):

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
}
}

我试图用 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

我一遍又一遍地阅读 Rust Book,以及关于所有权和借用的部分。我在 StackOverflow 上阅读了很多关于这个问题的问题,例如:

Cannot move out of borrowed content

我不认为我自己的问题是重复的,因为虽然错误相同,但情况不同。另外,如果我知道其他问题如何适用于这个问题,我就不必问了。 :-)

所以我的问题是:我该如何解决这个错误?我不想将 &self 更改为 self,因为这会导致其他问题。

除了解决问题,我还想知道 Rust 害怕什么。我在这里看不到任何危险。

最佳答案

您在 Money 而不是 &Money 上实现运算符。这意味着运算符将取得其操作数的所有权。因此,在 total 中,要执行加法,您必须移动 self.absolute,这是不允许的,因为您无法移出借用的指针(您只能移动您拥有的值)。如果 Rust 的类型实现了 Copy,Rust 将复制值(像 i32f64 这样的原语就是这种情况);否则,它将移动它们,这意味着移动后源将不可用。

如果你的 Money 结构真的只包含一个 cents 字段,我建议你让它实现 Copy (这也需要实现 Clone ,即使您不实现 Copy,这也是实现的好主意)。您可以使用 #[derive] 轻松实现 CopyClone:

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct Money {
cents: i64,
}

现在,在 total 中,Rust 不会移动 self.absolute,而是复制它。如果您无法实现 Copy,请将 self.absolute 替换为 self.absolute.clone()


如果您已经在 &Money 上实现了运算符,那么您可以只传递对您的 Money 值的引用。例如,通过这样的实现,total 可以这样实现:

pub fn total(&self, basis: Money) -> Money {
&self.absolute + &(self.percent * &basis)
}

关于rust - "cannot move out of borrowed content"运算符重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37313335/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com