将Ref <Box <dyn Any >>向下转换到Ref <Box <T >>

问题描述

我需要编写一个函数foo,该函数采用一个&RefCell<Box<dyn Any>>,从RefCell借用并返回一个向下转换的对象。向下转换的类型是在运行时选择的,但在此示例中,我们假设其为usize

use core::any::Any;
use std::cell::{RefCell,Ref};

pub fn foo<T: 'static>(cell: &RefCell<Box<dyn Any>>) -> Option<Ref<Box<T>>> {
    ???
}

pub fn main() {

    let boxed: Box<dyn Any> = Box::new(1 as usize);
    let cell = RefCell::new(boxed);

    let num = foo(&cell);
    println!("x: {}",num.unwrap());
}

我尝试过这样实现foo

// 1:
pub fn foo<T: 'static>(cell: &RefCell<Box<dyn Any>>) -> Option<Ref<Box<T>>> {
    let borrowed_cell = Ref::map(cell.borrow(),|borrow| borrow.downcast_ref::<T>().unwrap());
    Some(borrowed_cell)
}

此版本的问题在于它假设downcast_ref将一直有效,但是我想捕获一个downcast_ref错误。 下面,我尝试以一种可以捕获错误的方式实现foo

// 2:
pub fn foo<T: 'static>(cell: &RefCell<Box<dyn Any>>) -> Option<Ref<T>> {
    {
        cell.borrow().downcast_ref::<T>()?;
    }

    let borrowed_cell = Ref::map(cell.borrow(),|borrow| borrow.downcast_ref::<T>().unwrap());
    Some(borrowed_cell)
}

此版本可以捕获下降错误,但必须调用downcast_ref两次(这可以接受,但是我想知道是否有更好的方法)。当尝试仅使用downcast_ref一次时,我陷入了终身错误。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)