Rust Prevent不能将“*self”作为不可变项借用,因为在访问结构中不相交的字段时,它也作为可变项借用?

Rust Prevent不能将“*self”作为不可变项借用,因为在访问结构中不相交的字段时,它也作为可变项借用?,rust,borrow-checker,Rust,Borrow Checker,之前的问题,这不是重复的: 这个问题与b/c无关,答案是“Rust编译器有一个bug”,我很确定这里不是这样 我有以下结构: structfoo{ 资料来源:Vec, a:使用, } 结构条{ b:使用 } 在impl Foo中,我有以下方法: fn示例(&mut self,c:usize){ 设baz=&mut self.data[c]; 设z=自计算(c); baz.b=42+z; } fn计算(&self,x:usize)->usize{ self.a*x } 当然,Rus

之前的问题,这不是重复的:

    • 这个问题与b/c无关,答案是“Rust编译器有一个bug”,我很确定这里不是这样
我有以下结构:

structfoo{
资料来源:Vec,
a:使用,
}
结构条{
b:使用
}
impl Foo
中,我有以下方法:

fn示例(&mut self,c:usize){
设baz=&mut self.data[c];
设z=自计算(c);
baz.b=42+z;
}
fn计算(&self,x:usize)->usize{
self.a*x
}
当然,Rust编译器会抛出一个错误,大致说“当您创建
baz
时会发生可变借用,然后当您调用
self.calc
时会执行不可变借用,最后当您分配给
baz.a
时会使用可变借用”

但是,我正在访问结构上不相交的字段,因为
calc
从不读取通过
baz
写入的数据


有没有办法通知Rust编译器这一点?

问题是
Foo::calc
的签名,它将
&self
作为接收者。这保证
calc
不存在对所有
self
的可变引用,包括其任何字段;也就是说,所有
Foo
都保证被删除从
calc
主体的角度来看是不可变的。这在代码本身是不可能的,因为
self.calc(c)
要求在可变借用仍处于活动状态时不可变地借用
self
(所有
self

calc
从不读取写入
baz
的数据这一事实是无关紧要的。在Rust中,关于函数或方法的所有知识都暴露在签名中;编译器从不“查看”函数以确定它是否是特例

您可以通过不要求
calc
&self
作为接收方来避免此问题。例如,在调用之前借用单个字段(
self::calc(&self.a,c)
),或者,如以下示例所示,完全不借用
self

impl Foo {
    fn example(&mut self, c: usize) {
        let baz = &mut self.data[c];
        // This avoids borrowing `self` in its entirety...
        let z = Self::calc(self.a, c);
        baz.b = 42 + z;
    }

    fn calc(a: usize, x: usize) -> usize {
        a * x
    }
}
我最后做了:

fn示例(&mut self,c:usize){
设baz=&self.data[c];
//一些需要阅读的东西`
设z=自计算(c);
设baz=&mut self.data[c];
baz.b=42+z;
}
fn计算(&self,x:usize)->usize{
self.a*x
}

非常确定没有。在示例代码中,您可以移动
baz
的声明,实际的解决方法也将类似地针对具体情况。在这方面,您是否有更接近实际代码的示例?