在Rust中如何定义可存储任意基本数据类型的数组或Vector?
首先你原来的写法无法编译的核心原因是:std::any::Any是动态大小类型(DST),没有固定的编译期内存大小,Rust不允许直接将这类类型作为数组或者Vector的元素,必须用固定大小的智能指针包裹后才能使用。
正确实现方案
方案1:动态长度的Vector实现
日常场景优先用这个方案,存储任意类型元素的写法如下:
use std::any::Any; fn main() { // 声明元素类型为Box<dyn Any>的Vector let mut any_vec: Vec<Box<dyn Any>> = Vec::new(); // 插入不同基础类型的元素 any_vec.push(Box::new(18)); // i32类型 any_vec.push(Box::new(6.8)); // f64类型 any_vec.push(Box::new("测试文本")); // &str类型 any_vec.push(Box::new(true)); // bool类型 // 读取元素需要做类型向下转换 for elem in any_vec { match elem.downcast::<i32>() { Ok(num) => println!("读取到整数:{num}"), Err(elem) => match elem.downcast::<f64>() { Ok(float) => println!("读取到浮点数:{float}"), Err(elem) => match elem.downcast::<&str>() { Ok(s) => println!("读取到字符串:{s}"), Err(elem) => if let Ok(b) = elem.downcast::<bool>() { println!("读取到布尔值:{b}") } } } } } }
方案2:固定长度的数组实现
如果需要固定长度的集合,写法如下:
use std::any::Any; fn main() { // 固定长度为4的任意类型数组 let any_arr: [Box<dyn Any>; 4] = [ Box::new(100), Box::new(3.14), Box::new("数组测试"), Box::new(false) ]; // 访问指定位置元素 if let Some(num) = any_arr[0].downcast_ref::<i32>() { println!("数组第一个元素为整数:{num}"); } }
注意事项
- 所有存入的类型默认需要满足
'static生命周期约束,这是Anytrait的内置要求,如果需要存储带非静态生命周期的元素,需要自行实现自定义的类型擦除逻辑。 - 读取元素时必须显式做类型转换,类型不匹配时无法拿到对应值,运行时不会做隐式类型转换。
内容的提问来源于stack exchange,提问作者ferd tomale
相关产品推荐
相关产品推荐

