不能借用不可变 'Box' 内容作为可变内容
Cannot borrow immutable 'Box' content as mutable
我正在尝试使用静态变量通过 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
看起来 "cannot borrow immutable Box content as mutable" 问题简化为:
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();
}
我正在尝试使用静态变量通过 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
看起来 "cannot borrow immutable Box content as mutable" 问题简化为:
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();
}