简体   繁体   English

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

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

I have following code that can't be compiled:我有以下无法编译的代码:

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

The error is:错误是:

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

How to pass self as the argument of add_assign ?如何将self作为add_assign的参数add_assign I have tried &self , *self , &*self without success.我试过&self , *self , &*self没有成功。

For the current version of the question对于问题的当前版本

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

Your request is impossible.你的要求是不可能的。

You cannot have a mutable reference and an immutable reference to the same value at the same time.您不能同时拥有对同一值的可变引用和不可变引用。 This is a fundamental aspect of Rust.这是 Rust 的一个基本方面。

Please re-read the rules of references .请重新阅读参考规则

See also:也可以看看:

For the first version of the question对于问题的第一个版本

fn add_assign(&mut self, other: Self)

Your request is impossible.你的要求是不可能的。

You need one instance of struct A to call the method on and another instance of A to pass as the argument.你需要结构的一个实例A调用的方法的另一个实例, A以作为参数传递。 Your type does not implement Copy or Clone or provide any equivalent methods so there is no way to get a second instance.您的类型未实现CopyClone或提供任何等效方法,因此无法获得第二个实例。

Beyond that, there's no universal way to take a mutable reference to a value and get an owned value out of it.除此之外,没有通用的方法来获取对值的可变引用并从中获取拥有的值。

See also:也可以看看:

Workarounds解决方法

If you implement Copy or Clone , then you can get a second value from the original and then call either of your versions.如果您实现CopyClone ,那么您可以从原始值中获取第二个值,然后调用您的任一版本。

If you implemented Copy :如果您实施了Copy

  • (other: Self)

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

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

If only Clone :如果只是Clone

  • (other: Self)

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

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

You probably want to implement the AddAssign trait to provide syntax sugar.您可能想要实现AddAssign trait 来提供语法糖。 Assuming you've implemented Copy :假设你已经实现了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;
    }
}

Stargateur's comment may also be applicable, as i32 implements Copy : Stargateur 的评论也可能适用,因为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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM