首页 文章

错误的根源是什么?“无法摆脱借来的内容”?

提问于
浏览
0

我永远不明白为什么我收到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

这种错误的起源是什么?

1 回答

  • 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>>> . 这很好,因为您不想取得容器或其值的所有权 .

    然后你匹配 iterSome(ref x) . 较旧的编译器版本将失败,因为您匹配对非引用的引用,但新的编译器将执行,如果您匹配 Option<&T> 而不是 &Option<T> (如果需要) . 这很方便,意味着你只能写 Some(x) =>x 将是 &Rc<RefCell<user_type>> 而不是 &&Rc<..> (不是真的很重要,自动解除引用将使这些等效) .

    现在你用 &Rc<RefCell<..>> 调用 x.into_inner() ,这将无法工作 . 看起来你想把 RefCell 变成不需要的 tempRc 实现 Deref 所以你可以免费获得 . 相反,编译器认为您正在调用 RefCell::into_inner(self) -> T ,但此函数使用 self 来获取包含的值 . 你不拥有它,你只是借用它 . 这就是错误消息的含义:您正在尝试使用(移出)和您不拥有的对象(借用) .

    你真正想要的只是借用 user_type 足以召唤 to_string()

    Some(x) => { 
        let temp = x.borrow().to_string();
        result += &temp;
    }
    

相关问题