You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Box<dyn T>何时可强制转换为&dyn T?及as_any模式异常排查

关于Rust中Box调用as_any模式的类型判断问题

背景

我出于兴趣跟随教程编写一个简单解释器,需要判断Box<dyn Expr>中的实例是否为实现了Expr trait的Variable类型,采用了as_any模式。

测试代码与异常现象

最初的测试代码如下:

let e: Box<dyn Expr> = Box::new(Variable{ 
        name: Token{ token_type: TokenType::Number, lexeme: "123".to_string(), literal: Some(LoxValue::Number(123f64)), line: 1 } 
    });
assert!(e.as_any().is::<Variable>());
assert!(e.as_any().downcast_ref::<Variable>().is_some());

这段代码断言成功,且Rust Analyzer提示:

Type Box<dyn Expr, Global> Coerced to: &dyn Expr

但在其他场景中无法复现该行为,必须写(*the_box).as_any().is::<SomeStruct>()才能得到正确结果,否则判断始终返回false。

相关类型定义

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

impl<T: Any> AsAny for T  {
    fn as_any(&self) -> &dyn Any {
        self
    }
}

pub trait Expr: AsAny + Debug{
    fn evaluate(&self, environment: &mut Environment) -> EvaluateResult;
    fn boxed(self) -> Box<dyn Expr> where Self: Sized {
        Box::new(self)
    }
}

#[derive(Debug)]
pub struct Variable {
    pub name: Token,
}

impl Expr for Variable {
    fn evaluate(&self, environment: &mut Environment) -> super::expr::EvaluateResult {
        environment.get(self.name.clone())
    }
}

复现测试

在新创建的包中编写如下代码:

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

impl<T: Any> AsAny for T  {
    fn as_any(&self) -> &dyn Any {
        self
    }
}

struct Foo  {}

trait TheTrait: AsAny {}

impl TheTrait for Foo {}

fn main() {
    let b: Box<dyn TheTrait> = Box::new(Foo{});
    println!("{}", b.as_any().is::<Foo>());
    println!("{}", (*b).as_any().is::<Foo>());
}

运行后只有第二行println!输出true。

更新说明

(*boxed_thing).as_any().is::<SomeThing>()似乎才是正确写法。可能存在某种bug导致boxed_thing.as_any().is::<Something>()偶然生效,将原代码复制到新位置后断言失败。


内容的提问来源于stack exchange,提问作者Lee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 23:47:43