我从不理解为什么我收到Rust错误“无法移出借用的内容”。
let objFromLocalStorage =
localStorage.getItem('coordinates');
完整的错误消息是:
use std::cell::RefCell;
use std::collections::VecDeque;
use std::rc::Rc;
use std::vec::Vec;
pub struct user_type {
pub name: String,
pub ilist: Vec<i32>,
pub user_type_list: VecDeque<Option<Rc<RefCell<user_type>>>>,
pub parent: Option<Rc<RefCell<user_type>>>,
}
impl user_type {
pub fn new(name: String) -> Self {
user_type {
name: name.clone(),
ilist: Vec::new(),
user_type_list: VecDeque::new(),
parent: Option::None,
}
}
pub fn to_string(&self) -> String {
let mut result: String = String::new();
result += "name is ";
result += &self.name;
let n = self.user_type_list.len();
for iter in &self.user_type_list {
match iter {
Some(ref x) => {
let temp = x.into_inner();
let temp2 = temp.to_string();
result += &temp2[..];
}
None => panic!("to_string"),
}
result += "\n";
}
result
}
}
这种错误的起因是什么?
答案 0 :(得分:0)
仔细查看以下代码:
for iter in &self.user_type_list {
match iter {
Some(ref x) => {
let temp = x.into_inner();
let temp2 = temp.to_string();
result += &temp2[..];
}
None => panic!("to_string"),
}
result += "\n";
}
在这里,您要迭代&self.user_type_list
,因此iter
的类型实际上是对所包含的值&Option<Rc<RefCell<user_type>>>
的引用。很好,因为您不想获取容器或其值的所有权。
然后将iter
匹配到Some(ref x)
。较旧的编译器版本将失败,因为您将引用与非引用进行了匹配,但是如果需要,新的编译器将像匹配Option<&T>
而不是&Option<T>
一样进行操作。这很方便,意味着您可以只写Some(x) =>
,而x
的类型将是&Rc<RefCell<user_type>>
而不是&&Rc<..>
(这并不重要,自动取消引用将使等效)。
现在,您正在使用x.into_inner()
来呼叫&Rc<RefCell<..>>
,这将永远无法进行。似乎您想将RefCell
放入不需要的temp
中,Rc
实现了Deref
,因此您可以免费获得它。相反,编译器认为您正在调用RefCell::into_inner(self) -> T
,但是此函数使用self
来获取所包含的值。而且您不拥有它,只是借用了它。这就是错误消息的含义:您正在尝试消耗(移出)和不拥有的对象(借入)。
您真正想要的只是借用user_type
足以打电话给to_string()
:
Some(x) => {
let temp = x.borrow().to_string();
result += &temp;
}