为何无法对可变引用借用不可变引用?Rust编译报错咨询
Rust可变引用借用报错解析
问题代码
let mut v = vec![1, 2, 3]; let r = &mut v; let rr = &r; r.push(4); println!("{:?}, {:?}", r, rr);
编译错误信息
error[E0502]: cannot borrow `*r` as mutable because it is also borrowed as immutable | 86 | let rr = &r; | -- immutable borrow occurs here 87 | r.push(4); | ^^^^^^^^^ mutable borrow occurs here 88 | println!("{:?}, {:?}", r, rr); | -- immutable borrow later used here
用户疑问
我理解*r被可变借用后就不能再被不可变借用的规则,但这里我借的是r的不可变引用,不是*r的,为啥会报错?
问题解析
这问题的核心是Rust里引用的可变性会间接关联到底层数据:
r是个&mut Vec<i32>类型的可变引用,你写let rr = &r,其实是拿了这个可变引用本身的不可变引用(类型是&&mut Vec<i32>)。- 但别小看这个
&r,因为你能通过rr间接访问到*r(比如**rr就是原数组),所以Rust会判定:*r已经被这个rr间接做了不可变借用。 - 当你调用
r.push(4)时,需要对*r做可变借用,但此时*r已经被rr“锁定”了(不可变借用要求数据不能被修改),所以直接触发了E0502的错误。
说白了就是:只要你拿着可变引用的不可变引用,就别想再用原可变引用改数据了——Rust要保证所有不可变引用看到的都是稳定不变的数据。
要让代码跑起来也简单,把rr的生命周期限制在r.push(4)之前就行:
let mut v = vec![1, 2, 3]; let r = &mut v; { let rr = &r; println!("{:?}", rr); } // 这里rr就销毁了,借用结束 r.push(4); println!("{:?}", r);
内容的提问来源于stack exchange,提问作者Helin Wang
相关产品推荐
相关产品推荐

