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
的声明,实际的解决方法也将类似地针对具体情况。在这方面,您是否有更接近实际代码的示例?