按照我的理解,如果不是完全没有必要的话,Rust 中没有基本类型的必要性。
请注意,参数多态性(泛型)的引入已经删除了 Object 的大部分用例,也在 java 中。
使用Object,您可以实现一个“通用”方法,该方法适用于任何类型的java 类型。另一方面,当你有一个 Object 时,你不能用它做很多事情......你必须将它转换回实际的子类型才能使用它。
例如,Java 集合的旧非泛型版本与 Objects 一起使用,这意味着您必须像这样工作(示例直接来自 this post on Oracle's site):
LinkedList list = new LinkedList();
list.add(new Integer(1));
Integer num = (Integer) list.get(0);
add 采用Object(因此您可以使用任何类型的集合)。但是get 也返回一个Object,因此您必须根据您(程序员)对您最初插入到LinkedList 中的内容的了解将其转换回Integer。这里几乎没有类型安全性。
同一个容器的新通用版本,从 java 1.5 开始,是:
LinkedList<Integer> list = new LinkedList<Integer>();
list.add(new Integer(1));
Integer num = list.get(0);
现在你有一个Integer 的列表,所以add 接受Integer 和get 返回Integer。 Object 已无处可见(尽管由于类型擦除,它就在那里,几乎没有隐藏在引擎盖下......)
请注意,Go 对 interface{} 的主要使用源于 Go 没有泛型这一事实。 interface{} 的主要使用模式大致相同。当您必须使用多种类型并且在使用它之前将其(although in a safer way 和a more elegant pattern)转换回更有用的类型时,您可以使用它。
考虑到这一点,理论上你可以在 Rust 中以相同的方式使用Any(在使用之前检查实际类型并强制转换)。只是您可能不会发现很多这可能有用的情况。
下面的代码适用于 rustc 0.13-nightly (2015-01-01),尽管我确信有更好的方法来编写它......
use std::any::{Any, AnyRefExt};
// just a couple of random types
struct Foo {
a: f64
}
enum Bar {
Baz(int),
Qux
}
fn main() {
// create an array of things that could have any type
let anything = &[&1i as &Any, &Foo{a: 2.} as &Any, &Bar::Qux as &Any];
// iterate and print only the integer
for &any in anything.iter() {
if any.is::<int>() { // check if type is int
match any.downcast_ref::<int>() { // cast to int
Some(a) => { println!("{}", *a); }
None => panic!()
}
// or just (shorter version of the match)
println!("{}", *any.downcast_ref::<int>().unwrap());
}
}
}