如何从闭包内部修改Rc <refcell>?

时间:2016-01-10 20:30:16

标签: rust

我试图将RefCell传递给闭包中的函数,然后从闭包内部修改相同的变量。这是我的代码:

let path: Rc<RefCell<Option<Vec<PathBuf>>>> = Rc::new(RefCell::new(None));

...
//valid value assigned to path
...

let cloned_path = path.clone();

button_run.connect_clicked(move |_| {
    let to_remove: usize = open_dir(&mut cloned_path.borrow_mut().deref_mut());
    //Here I need to remove "to_remove" index from cloned_path
});

//Choose a random directory from Vec and open it. Returns opened index.
fn open_dir(path_two: &mut Option<Vec<PathBuf>>) -> usize {
    let vec = path_two.clone();
    let vec_length = vec.unwrap().len();

    let mut rng = thread_rng();
    let rand_number = rng.gen_range(0, vec_length);

    let p: &str = &*path_two.clone().expect("8")[rand_number].to_str().unwrap().to_string();

    Command::new("explorer.exe").arg(p).output();

    rand_number.clone()
}

首先我认为,由于我的open_dir()函数接受&mut,我可以修改函数内部的向量。但无论我尝试什么,我都会遇到cannot move out of borrowed content错误。 然后我想 - 好吧,我可以从函数返回索引并从闭包本身访问cloned_path。但是我可以编译的唯一代码是

button_run.connect_clicked(move |_| {
    let to_remove: usize = open_dir(&mut cloned_path.borrow_mut().deref_mut());
    let x = &*cloned_path.borrow_mut().clone().unwrap().remove(to_remove);
});

它有效,但它从cloned_path的克隆版本中删除,原始版本不受影响。有没有办法直接访问cloned_path来修改它的内容,如果有的话,我该如何处理这个任务?

1 个答案:

答案 0 :(得分:1)

修改枚举值(和Option是enum)内容的主要方法是模式匹配:

fn do_something(path_two: &mut Option<Vec<PathBuf>>) {
    if let Some(ref mut paths) = *path_two {
        paths.push(Path::new("abcde").to_path_buf());
    }
}

请注意,paths模式变量与ref mut限定符绑定 - 这意味着它将是&mut Vec<PathBuf>类型,即对选项内部的可变引用,修改矢量所需的内容,以防它存在。