为了扩展 rightføld 的评论,Any 是您在 Rust 中真正可以得到的最接近的,尽管它确实有一个主要限制:它仅由满足'static 生命周期的类型;也就是说,您不能将任何包含非静态引用的类型视为Any。
第二个复杂情况是 Java 中的 Object 具有引用语义并为您提供共享所有权。因此,您需要Rc<RefCell<Any>> 之类的东西才能获得大致可比的东西。但是请注意,强烈建议不要这样做,因为它基本上会将大量检查转移到运行时。这样的事情应该是万不得已的后备。
最后,请注意,据我所知,除了已擦除类型之外,没有办法对 Any 进行动态向上转换。所以你不能引用一个实现Show的值,将其转换为&Any,然后向上转换为&Show。
如果适用,更好的替代方案包括泛化值类型(因此使用泛型函数和结构),如果您想要支持的类型是固定的、有限的列表,则使用 enum,或者编写和实现自定义特征,按这个顺序。
但是,为了给您一个使用 Any 的示例,我将以下内容放在一起。请注意,我们必须尝试显式向上转换为每种支持的类型。
#![feature(if_let)]
use std::any::{Any, AnyRefExt};
use std::collections::HashMap;
fn main() {
let val_a = box "blah";
let val_b = box 42u;
let val_c = box 3.14159f64;
let mut map = HashMap::new();
map.insert("a".into_string(), val_a as Box<Any>);
map.insert("b".into_string(), val_b as Box<Any>);
map.insert("c".into_string(), val_c as Box<Any>);
println!("{}", map);
splang(&map);
}
fn splang(map: &HashMap<String, Box<Any>>) {
for (k, v) in map.iter() {
if let Some(v) = v.downcast_ref::<&str>() {
println!("[\"{}\"]: &str = \"{}\"", k, *v);
} else if let Some(v) = v.downcast_ref::<uint>() {
println!("[\"{}\"]: uint = {}", k, *v);
} else {
println!("[\"{}\"]: ? = {}", k, v);
}
}
}
运行时输出:
{c: Box<Any>, a: Box<Any>, b: Box<Any>}
["c"]: ? = Box<Any>
["a"]: &str = "blah"
["b"]: uint = 42