从Vec的可变引用中借用可变元素时遇E0596错误求解
Rust可变引用借用编译错误问题
复现代码
struct MyStruct<'a> { pub vec: Option<&'a mut Vec<u8>>, } impl<'a> MyStruct<'a> { fn some_borrow(&mut self, index: usize) -> Option<&mut u8> { match &self.vec { None => println!("nope"), Some(vec) => match vec.get_mut(index) { None => println!("no elements"), Some(int) => return Some(int), } } return None; } } fn main() { let mut vec = vec![0, 1, 2]; let mut data = MyStruct{ vec: Some(&mut vec) }; data.some_borrow(1); }
编译错误信息
error[E0596]: cannot borrow `**vec` as mutable, as it is behind a `&` reference --> src/main.rs:9:32 | 9 | Some(vec) => match vec.get_mut(index) { | ^^^^^^^^^^^^^^^^^^ `vec` is a `&` reference, so the data it refers to cannot be borrowed as mutable
疑问
明明MyStruct里持有Vec<u8>的可变引用,为什么调用get_mut时会提示无法借用可变元素?
问题原因与修复方案
错误原因
你在match里用了&self.vec,这会对self.vec做一次不可变借用,得到的是&Option<&'a mut Vec<u8>>。匹配到Some(vec)时,这里的vec实际是&&'a mut Vec<u8>——也就是「对可变引用的不可变引用」。
Rust的借用规则不允许通过不可变引用修改内部数据,哪怕内部本身是可变引用也不行,所以你没法用这个vec调用需要可变借用的get_mut方法。
修复方法
方法一:匹配可变引用的Option
直接把&self.vec改成&mut self.vec,对self.vec做可变借用:
fn some_borrow(&mut self, index: usize) -> Option<&mut u8> { match &mut self.vec { None => println!("nope"), Some(vec) => match vec.get_mut(index) { None => println!("no elements"), Some(int) => return Some(int), } } None }
此时匹配到的vec是&mut &'a mut Vec<u8>,外层是可变引用,允许修改内部可变引用指向的数据,自然就能调用get_mut了。
方法二:用take()临时转移所有权
如果需要临时取出可变引用操作,之后再放回,可以用Option::take():
fn some_borrow(&mut self, index: usize) -> Option<&mut u8> { match self.vec.take() { None => println!("nope"), Some(mut vec) => match vec.get_mut(index) { None => { println!("no elements"); self.vec = Some(vec); // 用完把引用放回结构体 None } Some(int) => return Some(int), } } None }
方法三:用if let简化代码
如果不需要复杂的分支打印逻辑,用if let能让代码更简洁:
fn some_borrow(&mut self, index: usize) -> Option<&mut u8> { if let Some(vec) = &mut self.vec { vec.get_mut(index) } else { println!("nope"); None } }
内容的提问来源于stack exchange,提问作者LucioleMaléfique
相关产品推荐
相关产品推荐

