Rust如何实现trait向下转型为具体struct(类似C#类型转换)
解决方案
要实现 trait 对象向下转型为具体结构体的功能,需要借助 Rust 标准库的 std::any::Any trait 完成运行时类型识别,修改后的可运行代码如下:
use std::any::Any; trait Base: Any { fn base_method(&self); // 辅助方法:将自身转为 `&dyn Any` 供后续转型使用 fn as_any(&self) -> &dyn Any { self } } struct Derived1; impl Derived1 { pub fn derived1_method(&self) { println!("Derived1"); } } impl Base for Derived1 { fn base_method(&self) { println!("Base Derived1"); } } struct Derived2; impl Derived2 { pub fn derived2_method(&self) { println!("Derived2"); } } impl Base for Derived2 { fn base_method(&self) { println!("Base Derived2"); } } fn main() { let mut bases = Vec::<Box<dyn Base>>::new(); let der1 = Derived1{}; let der2 = Derived2{}; bases.push(Box::new(der1)); bases.push(Box::new(der2)); for b in bases { b.base_method(); // 类型判断与转型逻辑 if let Some(der1) = b.as_any().downcast_ref::<Derived1>() { der1.derived1_method(); } else if let Some(der2) = b.as_any().downcast_ref::<Derived2>() { der2.derived2_method(); } } }
运行代码输出结果为:
Base Derived1 Derived1 Base Derived2 Derived2
实现原理
- 所有带有
'static生命周期的类型都会自动实现Anytrait,可用于运行时获取类型信息 - 要求
Base继承Any后,所有实现Base的结构体都可以通过as_any方法转为通用的Any类型对象 downcast_ref::<T>方法会尝试将&dyn Any转型为指定类型T的不可变引用,转型成功返回Some(&T),失败返回None,配合if let语法即可实现类型判断+专属方法调用的需求
内容的提问来源于stack exchange,提问作者PrinceOfBorgo
相关产品推荐
相关产品推荐

