如何将对 self 的可变引用转换为不可变引用以用作方法的参数?

How do I convert a mutable reference to self into an immutable reference to be used as an argument for a method?

我有以下无法编译的代码:

struct A {
    x: i32,
}

impl A {
    fn add_assign(&mut self, other: &Self) {
        self.x += other.x;
    }

    fn double(&mut self) {
        self.add_assign(self);
    }
}

错误是:

error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable
  --> src/lib.rs:11:9
   |
11 |         self.add_assign(self);
   |         ^^^^^----------^----^
   |         |    |          |
   |         |    |          immutable borrow occurs here
   |         |    immutable borrow later used by call
   |         mutable borrow occurs here

如何将self作为add_assign的参数传递?我试过 &self*self&*self 都没有成功。

对于当前版本的问题

fn add_assign(&mut self, other: &Self)

你的请求是不可能的。

您不能同时拥有对同一值的可变引用和不可变引用。这是 Rust 的一个基本方面。

请重新阅读the rules of references

另请参阅:

对于first version的问题

fn add_assign(&mut self, other: Self)

你的请求是不可能的。

您需要一个结构 A 的实例来调用该方法,并且 另一个 A 的实例作为参数传递。您的类型未实现 CopyClone 或提供任何等效方法,因此 无法 获得第二个实例。

除此之外,没有通用的方法来获取对值的可变引用并从中获取拥有的值。

另请参阅:

解决方法

如果您实施 CopyClone,则您可以从原始值中获取第二个值,然后调用您的任一版本。

如果您实施了 Copy

  • (other: Self)

    self.add_assign(*self);
    
  • (other: &Self)

    let other = *self;
    self.add_assign(&other);
    

只要Clone:

  • (other: Self)

    self.add_assign(self.clone());
    
  • (other: &Self)

    self.add_assign(&self.clone());
    

您可能想要实现 AddAssign 特性来提供语法糖。假设您已经实施 Copy:

impl A {
    fn double(&mut self) {
        *self += *self;
    }
}

impl std::ops::AddAssign<Self> for A {
    fn add_assign(&mut self, other: Self) {
        self.x += other.x;
    }
}

也可能适用,因为 i32 实现了 Copy:

impl A {
    fn double(&mut self) {
        *self += self.x;
    }
}

impl std::ops::AddAssign<i32> for A {
    fn add_assign(&mut self, other: i32) {
        self.x += other;
    }
}