【问题标题】:refcell rc<refcell<>> doesn't changerefcell rc<refcell<>> 不会改变
【发布时间】:2021-07-11 05:14:47
【问题描述】:

这是我的简化代码。我需要更改函数中的 pdp_state。但状态仍然是'a'。我不明白为什么克隆 Rc 不起作用。我还检查了这个克隆的结构,它工作正常。

#[derive(Clone,Copy)]
enum PDPStatus{
    a,
    b
}
struct network{
    pdp_state:Rc<RefCell<PDPStatus>>,
}
impl network{
    fn set(&mut self){
        let mut t = *self.pdp_state.clone().borrow_mut();
        match t {
            a => {let m1 = self.pdp_state.clone();
                let mut a = (*m1).borrow_mut() ;
                *a = PDPStatus::b;
                println!("a");},
            b=> {let m1 = self.pdp_state.clone();m1.replace( PDPStatus::a);
                println!("b");},
        };

    }
}
fn main() {
    let mut network1 = network::new();
    network1.set();
    network1.set();
    network1.set();
    network1.set();
}

更新: 我的 set 函数看起来像这样。我需要两个可以访问 pdp_state 的闭包。我将这些闭包作为回调传递。我确信这些闭包不会一起调用。

    fn set(&mut self){
        let borrowed_pdp_status = self.pdp_state.borrow().clone();
        match borrowed_pdp_status {
            PDPStatus::a => {
                let mut state = self.pdp_state.clone();
                let mut closuree = || state =  Rc::new(RefCell::new(PDPStatus::b));
                let mut state1 = self.pdp_state.clone();
                let mut closuree1 = || state1 = Rc::new(RefCell::new(PDPStatus::b));

                closuree();
                closuree1();
                println!("a");
            },
            PDPStatus::b => {
                let mut closuree = || self.pdp_state = Rc::new(RefCell::new(PDPStatus::a));
                closuree();
                println!("b");
            },
        };
    }

【问题讨论】:

    标签: rust rc refcell


    【解决方案1】:

    set方法中,需要先borrowself.pdp_stateclone()在一个变量中,然后匹配你克隆的那个变量。

    set 方法替换为:

    fn set(&mut self) {
            let borrowed_pdp_status = self.pdp_state.borrow().clone();
            match borrowed_pdp_status {
                PDPStatus::a => {
                    self.pdp_state = Rc::new(RefCell::new(PDPStatus::b));
                    println!("a");
                },
                PDPStatus::b => {
                    self.pdp_state = Rc::new(RefCell::new(PDPStatus::a));
                    println!("b");
                },
            };
    }
    

    游乐场链接 - https://play.rust-lang.org/?version=stable&mode=release&edition=2018&gist=426d4cb7db9a92ee4ddcd4f36dbc12f7

    【讨论】:

    • 感谢您的回复。我不能使用 self.pdp_state 因为我需要借用状态来给它一个闭包。你有任何改变 pdp_status 的想法吗?
    • 你能提供一个你试图给pdp_state的闭包的例子吗?
    • 我更新了问题。感谢您的回复。
    • 我明白了,请检查我的其他答案。
    【解决方案2】:

    此答案是在问题更新后发布的:

    编辑

    您可以使用RefCell 中的replace() 方法

    fn set(&mut self) {
        let borrowed_pdp_status = self.pdp_state.borrow().clone();
        match borrowed_pdp_status {
            PDPStatus::a => {
                let mut closuree = || {
                    self.pdp_state.replace(PDPStatus::b);
                };
                let mut closuree1 = || {
                    self.pdp_state.replace(PDPStatus::b);
                };
    
                closuree();
                closuree1();
                println!("a");
            }
            PDPStatus::b => {
                let mut closuree = || {
                    self.pdp_state.replace(PDPStatus::a);
                };
                closuree();
                println!("b");
            }
        };
    }
    

    游乐场链接 - https://play.rust-lang.org/?version=stable&mode=release&edition=2018&gist=4af02228d58b2f2c865a525e3f70d6a0

    您可以让闭包将&amp;mut self.pdp_state 作为参数,然后对其进行更新。

    fn set(&mut self) {
        let borrowed_pdp_status = self.pdp_state.borrow().clone();
        match borrowed_pdp_status {
            PDPStatus::a => {
                let mut closuree = |local_pdp_state: &mut Rc<RefCell<PDPStatus>>| {
                    *local_pdp_state = Rc::new(RefCell::new(PDPStatus::b))
                };
                let mut closuree1 = |local_pdp_state: &mut Rc<RefCell<PDPStatus>>| {
                    *local_pdp_state = Rc::new(RefCell::new(PDPStatus::b))
                };
    
                closuree(&mut self.pdp_state);
                closuree1(&mut self.pdp_state);
                println!("a");
            }
            PDPStatus::b => {
                let mut closuree = |local_pdp_state: &mut Rc<RefCell<PDPStatus>>| {
                    *local_pdp_state = Rc::new(RefCell::new(PDPStatus::a))
                };
                closuree(&mut self.pdp_state);
                println!("b");
            }
        };
    }
    

    游乐场链接 - https://play.rust-lang.org/?version=stable&mode=release&edition=2018&gist=4af96385b0446082afdb7d615bb8eecb

    【讨论】:

    • 您好,感谢您的关注。正如我之前提到的,这些闭包将被传递给回调,不幸的是,我无法更改参数。
    • 奇怪,它在操场上确实有效:/
    猜你喜欢
    • 2019-12-13
    • 2023-01-20
    • 2021-04-06
    • 2020-01-15
    • 2022-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多