借用对struct中属性的引用

Ign*_*tin 5 rust

似乎如果你借用一个struct字段的引用,整个结构被认为是借用的.我设法隔离了我想要做的事情的例子.我只想获得一个字段的"只读"引用B来获取一些数据,然后修改另一个字段B.有没有惯用的Rust方法呢?

struct A {
    i: i32,
}

struct B {
    j: i32,
    a: Box<A>,
}

impl B {
    fn get<'a>(&'a mut self) -> &'a A {
        &*self.a
    }
    fn set(&mut self, j: i32) {
        self.j = j
    }
}

fn foo(a: &A) -> i32 {
    a.i + 1
}

fn main() {
    let a = Box::new(A { i: 47 });
    let mut b = B { a: a, j: 1 };
    let a_ref = b.get();
    b.set(foo(a_ref));
}
Run Code Online (Sandbox Code Playgroud)
error[E0499]: cannot borrow `b` as mutable more than once at a time
  --> src/main.rs:27:5
   |
26 |     let a_ref = b.get();
   |                 - first mutable borrow occurs here
27 |     b.set(foo(a_ref));
   |     ^ second mutable borrow occurs here
28 | }
   | - first borrow ends here
Run Code Online (Sandbox Code Playgroud)

Lev*_*ans 6

这是语言的一个特点。从编译器的角度来看,它无法知道set()a通过 借用时调用您的函数是安全的get()

您的get()函数可以b可变地借用,并返回一个引用,因此b将保持借用状态,直到该引用超出范围。

您有几种处理方法:

  1. 将您的两个字段分成两个不同的结构

  2. 移动需要访问两个属性的方法中的代码 B

  3. 公开你的属性,这样你就可以直接获得对它们的引用

  4. 在设置之前计算新值,如下所示:

    fn main() {
        let a = Box::new(A { i: 47 });
        let mut b = B { a: a, j: 1 };
        let newval = {
            let a_ref = b.get();
            foo(a_ref)
        };
        b.set(newval);
    }
    
    Run Code Online (Sandbox Code Playgroud)