I got a Box<Rc<RefCell<T>>>
from FFI. How can I get the &mut T
based on it?
I can not compile it. Compiler tells me:
47 | let mut r: &mut Server = server.borrow_mut();
| ^^^^^^^^^^ the trait BorrowMut<Server>
is not implemented for Box<Rc<RefCell<Server>>>
|
= help: the trait BorrowMut<T>
is implemented for Box<T, A>
For more information about this error, try rustc --explain E0277
.
#[derive(Debug)]
struct Server {
id: i32,
}
impl Server {
pub fn change_id(&mut self) {
self.id = self.id + 1;
}
}
#[no_mangle]
pub extern "C" fn server_change_id(server: *mut Rc<RefCell<Server>>) -> isize {
let server: Box<Rc<RefCell<Server>>> = unsafe { Box::from_raw(server) };
let mut r: &mut Server = server.borrow_mut();
r.change_id();
return 0;
}
Auto-deref will make borrow_mut()
directly accessible.
use std::{cell::RefCell, cell::RefMut, ops::DerefMut, rc::Rc};
fn main() {
let a = Box::new(Rc::new(RefCell::new("aaa".to_owned())));
//
println!("{:?}", a);
{
let mut r: RefMut<String> = a.borrow_mut();
r.push_str("bbb"); // via RefMut
let r2: &mut String = r.deref_mut();
r2.push_str("ccc"); // via exclusive-reference
}
println!("{:?}", a);
}
/*
RefCell { value: "aaa" }
RefCell { value: "aaabbbccc" }
*/
In your code, let mut r = server.borrow_mut();
should be enough to invoke r.change_id()
.
let mut r = server.borrow_mut();
r.change_id();
If you absolutely want a &mut
, then use let r2 = r.deref_mut()
and invoke r2.change_id()
.
let mut r = server.borrow_mut();
let r2 = r.deref_mut();
r2.change_id();
T gets wrapped inside the RefCell<T>
must implement the Deref
or DerefMut
trait in order to be borrowed mutably or reference borrowed. In your case, Server must implement a deref
method.
use std::ops::DerefMut;
impl DerefMut for Server {
fn deref_mut(&mut self) -> &mut Self {
*self // this assumes your server has more than just one i32 field.
}
}
After this implementation, you should be able to call server.borrow_mut()
should work perfectly and return you a mutable server object.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.