首页 > 解决方案 > 如何调试 downcast_ref 失败?

问题描述

由于 Rust 不支持向上转换,我正在尝试使用此处as_any提到的技巧,但使用参数化类型。但是,当我尝试调用返回的 Any 时,我得到. 由于我无法打印以找出它实际上是什么:downcast_refNoneAny

`dyn std::any::Any` doesn't implement `std::fmt::Display`

`dyn std::any::Any` cannot be formatted with the default formatter

我怎样才能调试它实际上是什么?这是失败的代码(游乐场):

use std::any::Any;
use std::rc::{Rc, Weak};

pub trait Wrapper: Any {
    fn as_any(&self) -> &dyn Any;
}

pub struct WeakWrapper<T: Any> {
    item: Weak<T>,
}

impl<'a, T: Any + 'static> Wrapper for WeakWrapper<T> {
    fn as_any(&self) -> &dyn Any {
        self
    }
}

fn main() {
    let rc = Rc::new(Box::new(5));
    let weak_wrapper = WeakWrapper {
        item: Rc::downgrade(&rc),
    };
    let item = weak_wrapper
        .as_any()
        .downcast_ref::<WeakWrapper<i32>>()
        .map(|w| w.item.upgrade().map(|n| *n))
        .flatten();
    println!("Item is {}", item.unwrap());
}

标签: rust

解决方案


WeakWrapper<i32>那是因为您正在向下转换为错误的类型:您正在尝试向下转换weak_wrapperWeakWrapper<Box<i32>>https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f49a3c2236beabae48a41d024a04d08f

因为我无法打印 Any 来找出它实际上是什么

您可以调试打印 TypeId,尽管它不是很有帮助(您会得到一个非常不透明的数字),但可以将其与 进行比较TypeId::of::<type>(),因此您可以这样做

any_value.type_id() == TypeId::of::<WeakWrapper<i32>>()

并发现它是false,但是

any_value.type_id() == TypeId::of::<WeakWrapper<Box<i32>>>()

是真的。


推荐阅读