简体   繁体   English

如何获得一个盒子的`&amp;mut T` <rc<refcell<t> &gt;&gt;? </rc<refcell<t>

[英]How to get `&mut T` of a Box<Rc<RefCell<T>>>?

I got a Box<Rc<RefCell<T>>> from FFI.我从 FFI 得到了一个Box<Rc<RefCell<T>>> How can I get the &mut T based on it?我怎样才能得到&mut T基于它?

I can not compile it.我无法编译它。 Compiler tells me:编译器告诉我:

47 | 47 | let mut r: &mut Server = server.borrow_mut();让 mut r: &mut 服务器 = server.borrow_mut();

| | ^^^^^^^^^^ the trait BorrowMut<Server> is not implemented for Box<Rc<RefCell<Server>>> ^^^^^^^^^^ 特征BorrowMut<Server>没有为Box<Rc<RefCell<Server>>>实现

| |

= help: the trait BorrowMut<T> is implemented for Box<T, A> = 帮助:为Box<T, A>实现了特征BorrowMut<T> >

For more information about this error, try rustc --explain E0277 .有关此错误的更多信息,请尝试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. Auto-deref 将使borrow_mut()可以直接访问。

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();在您的代码中, let mut r = server.borrow_mut(); should be enough to invoke r.change_id() .应该足以调用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() .如果您绝对想要&mut ,请使用let r2 = r.deref_mut()并调用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. T 被包裹在RefCell<T>中,必须实现DerefDerefMut特征才能被可变借用或引用借用。 In your case, Server must implement a deref method.在您的情况下, Server 必须实现deref方法。

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.在此实现之后,您应该能够调用server.borrow_mut()应该可以正常工作并返回一个可变服务器 object。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM