不能将不可变的'Box'内容借用为可变的

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不能将不可变的'Box'内容借用为可变的相关的知识,希望对你有一定的参考价值。

我试图通过使用静态变量的C回调提供闭包。我能够使用Fn类型工作,但我想通过FnMut使其工作,为库的用户提供更多功能。

这就是我所拥有的:

lazy_static! {
    static ref CALLBACK: Mutex<RefCell<Box<FnMut(Result<&str>) + Send>>> = Mutex::new(RefCell::new(Box::new(|_|())));
}

fn wrap_cb<F: Fn(Result<&str>)>(f: Option<F>) -> Option<unsafe extern "C" fn(*mut c_char, size_t)> {
    match f {
        Some(_) => {
            unsafe extern "C" fn wrapped(msg: *mut c_char, len: size_t) {
                let s = std::str::from_utf8(std::slice::from_raw_parts(msg as *const u8, len))
                    .map_err(Error::from);
                let x = CALLBACK.lock().unwrap();
                x.borrow_mut()(s);
            }
            Some(wrapped)
        }
        None => None,
    }
}

这给出了错误:

error[E0596]: cannot borrow immutable `Box` content as mutable
  --> src/wpactrl.rs:56:17
   |
56 |                 x.borrow_mut()(s);
   |                 ^^^^^^^^^^^^^^ cannot borrow as mutable
答案

看起来“无法借用不可变的Box内容为可变”的问题减少为:

fn invoke(m: &Mutex<RefCell<Box<FnMut()>>>) {
    let r = m.lock().unwrap();
    r.borrow_mut()();
}

我还没弄清楚为什么会这样,但如果改为:

fn invoke(m: &Mutex<RefCell<Box<FnMut()>>>) {
    let r = m.lock().unwrap();
    let f = &mut *r.borrow_mut();
    f();
}

以上是关于不能将不可变的'Box'内容借用为可变的的主要内容,如果未能解决你的问题,请参考以下文章

Swift 2在协议扩展中使用变异函数时出错“无法在不可变值上使用变异成员:'self'是不可变的

如何在未选中时使check_box_tag发布'false'或'0'参数?

将 CSDN 的文章保存成 PDF 文件

Visual Studio 2013将不显示Winforms,错误“项目中已存在对组件的引用'系统'

目标检测计算两个标注框的交并比(python代码)

python-字典