首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >match + RefCell =X寿命不够长

match + RefCell =X寿命不够长
EN

Stack Overflow用户
提问于 2016-07-06 05:56:20
回答 1查看 780关注 0票数 2

我需要初始化一个项目(fn init(&mut self) -> Option<&Error>),如果没有错误,就使用它。

代码语言:javascript
复制
pub fn add(&mut self, mut m: Box<Item>) {
    if let None = m.init() {
        self.items.push(m);
    }
}

这是有效的,除非我需要检查错误,如果有:

代码语言:javascript
复制
pub fn add(&mut self, mut m: Box<Item>) {
    if let Some(e) = m.init() {
        //process error
    } else {
        self.items.push(m); //won't compile, m is borrowed
    }
}

很公平。需要使用RefCell。然而,这

代码语言:javascript
复制
pub fn add(&mut self, mut m: Box<Item>) {
    let rc = RefCell::new(m);

    if let Some(e) = rc.borrow_mut().init() {           
        //process error         
    } else {
        self.items.push(rc.borrow_mut())
    }
}

以怪异结尾

代码语言:javascript
复制
error: `rc` does not live long enough
        if let Some(e) = rc.borrow_mut().init() {
                     ^~
note: reference must be valid for the destruction scope surrounding block at 75:60...
    pub fn add_module(&mut self, mut m: Box<RuntimeModule>) {
                                                        ^
note: ...but borrowed value is only valid for the block suffix following statement 0 at 76:30
        let rc = RefCell::new(m);

我几乎什么都试过了:普通盒子,Rc'ed盒子,RefCell'ed盒子,Rc'ed RefCell。试着让this answer适应我的情况,但没有用。

完整示例:

代码语言:javascript
复制
use std::cell::RefCell;
use std::error::Error;

trait Item {
    fn init(&mut self) -> Option<&Error>;
}

struct ItemImpl {}

impl Item for ItemImpl {
    fn init(&mut self) -> Option<&Error> {
        None
    }
}

//===========================================

struct Storage {
    items: Vec<Box<Item>>,
}

impl Storage {
    fn new() -> Storage {
        Storage{
            items: Vec::new(),
        }
    }

    fn add(&mut self, mut m: Box<Item>) {
        let rc = RefCell::new(m);

        if let Some(e) = rc.borrow_mut().init() {           
            //process error         
        } else {
            self.items.push(*rc.borrow_mut())
        }
    }
}

fn main() {
    let mut s = Storage::new();
    let mut i = Box::new(ItemImpl{});
    s.add(i);
}

(Playground)

UPD:正如所建议的,这是一个像我一样的“家庭”错误,这很好地解释了here。然而,我的案例有更简单的解决方案。

EN

回答 1

Stack Overflow用户

发布于 2016-07-06 15:56:45

正如krdln建议的那样,解决此问题的最简单方法是在if块中返回,从而确定借阅的作用域:

代码语言:javascript
复制
fn add(&mut self, mut m: Box<Item>) {
    if let Some(e) = m.init() {
        //process error
        return;
    } 
    self.items.push(m);
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38213453

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档