rust - “无法移出借来的内容”错误的根源是什么?
问题描述
我一直不明白为什么我会收到 Rust 错误“无法移出借来的内容”。
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
}
}
完整的错误信息是:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:34:32
|
34 | let temp = x.into_inner();
| ^ cannot move out of borrowed content
这种错误的根源是什么?
解决方案
仔细看这段代码:
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)
. 较旧的编译器版本会失败,因为您将引用匹配到非引用,但如果需要,新编译器会像匹配 aOption<&T>
而不是 a一样&Option<T>
。Some(x) =>
这很方便,并且意味着您可以只编写x
类型&Rc<RefCell<user_type>>
而不是类型&&Rc<..>
(这并不重要,自动取消引用将使它们等效)。
现在你x.into_inner()
用 a打电话,&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;
}
推荐阅读
- javascript - 无法在我的 html 中链接 javascript 文件
- python - 如何编写一个函数,仅计算类数组对象的前 n 项并返回它们的总和?
- r - RcppTN .cpp 脚本在来源时有效,但在库中编译时无效
- android - RecyclerView item element(imageview)click
- javascript - 如何在 swiper 滑块“.swiper-wrapper”类上添加固定的过渡持续时间值?
- rest - REST API 设计:当 api 必须返回一个字段的相等和不相等列表时,如何处理这种情况?
- c# - 尝试在锚标记助手中使用自定义路由时出错
- r - 如何在 RMarkdown 中合并和打印多个代码块?
- c++ - 在 C++ 中将变量 wstring 分配给 Char 数组
- prometheus - 在普罗米修斯的一项工作中注册多个黑盒出口商