将 Ref<Box<dyn Any>> 向下转换为 Ref<Box<T>> 时处理向下转换错误
Handle downcast error when downcasting Ref<Box<dyn Any>> into Ref<Box<T>>
我需要编写一个函数 foo
,它接受一个 &RefCell<Box<dyn Any>>
,从 RefCell
和 returns 中借用一个向下转换的对象。向下转换类型是在运行时选择的,但对于这个例子,我们假设它是 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错误,但是它必须调用downcast_ref
两次(这可以接受,但我想知道是否有更好的方法)。当尝试只使用一次 downcast_ref
时,我遇到了生命周期错误。
经过一番修改后,我想出了这个解决方案。您可以在映射之前使用 Any::is<T>()
检查借用。
pub fn foo<T: 'static>(cell: &RefCell<Box<dyn Any>>) -> Option<Ref<T>> {
let borrowed = cell.borrow();
if borrowed.is::<T>() {
Some(Ref::map(borrowed, |x| x.downcast_ref::<T>().unwrap()))
} else {
None
}
}
Rust 游乐场link
我需要编写一个函数 foo
,它接受一个 &RefCell<Box<dyn Any>>
,从 RefCell
和 returns 中借用一个向下转换的对象。向下转换类型是在运行时选择的,但对于这个例子,我们假设它是 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错误,但是它必须调用downcast_ref
两次(这可以接受,但我想知道是否有更好的方法)。当尝试只使用一次 downcast_ref
时,我遇到了生命周期错误。
经过一番修改后,我想出了这个解决方案。您可以在映射之前使用 Any::is<T>()
检查借用。
pub fn foo<T: 'static>(cell: &RefCell<Box<dyn Any>>) -> Option<Ref<T>> {
let borrowed = cell.borrow();
if borrowed.is::<T>() {
Some(Ref::map(borrowed, |x| x.downcast_ref::<T>().unwrap()))
} else {
None
}
}
Rust 游乐场link