代码之家  ›  专栏  ›  技术社区  ›  Fomalhaut

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

  •  -1
  • Fomalhaut  · 技术社区  · 6 年前

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

    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

    1 回复  |  直到 6 年前
        1
  •  7
  •   Shepmaster Tim Diekmann    4 年前

    对于问题的当前版本

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

    请重读 the rules of references

    另见:

    对于 first version

    fn add_assign(&mut self, other: Self)
    

    你的要求是不可能的。

    A 在和上调用该方法 另一个 实例 A. Copy Clone 或提供任何等效方法,以便 获得第二次审判。

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

    权变措施

    如果你实施 复制 ,则可以从原始版本中获取第二个值,然后调用任何一个版本。

    如果你实施 复制 :

    • (other: Self)

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

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

    要是…就好了 克隆 :

    • (其他:本人)

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

    您可能想要实现 AddAssign trait提供语法糖。假设你已经实现了 :

    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 也可能适用于以下情况: i32 工具 复制 :

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