可以将以下C#代码转换为Rust吗?
dynamic x = 109;
x = "Hi";
我要求使用通用动态类型来创建动态值数组。例如:
var l = new dynamic[2];
l[0] = 102;
l[1] = "Hi";
答案 0 :(得分:4)
一种选择是使用Any
的向量(链接到测试版,因为稳定的文档没有显示为Any
定义的方法,但它们是稳定的):
use std::any::Any;
fn main() {
let mut v: Vec<Box<Any>> = vec![];
v.push(Box::new(102usize));
v.push(Box::new("Hi"));
for item in &v {
// to do an operation, it is necessary to downcast to
// a concrete type
if let Some(x) = item.downcast_ref::<usize>() {
println!("num = {:?}", x)
}
}
}
请注意,与dynamic
中的C#
相反,假设支持任何操作,类型Any
(Box<Any>
)的值仅支持在Any
(Box<Any>
和Any
)。调用具体类型的任何方法都需要向下转换。
我认为在Rust中不可能有类似dynamic
的C#类型。为了支持在动态值上调用任何方法,必须具有(完成)运行时反射支持,而Rust不提供它。
如果您知道将要调用的方法,那么最好的选择是定义特征并使用Box<Trait>
(在这种情况下不需要Any
)。
答案 1 :(得分:3)
不直接。您只需为x
创建新的绑定:
fn main() {
let x = 109;
let x = "Hi";
}
根据您的使用情况,您可以使用由特质或特征对象限制的泛型来实现类似的目标:
use std::fmt::Display;
fn main() {
let mut x: Box<Display> = Box::new(109);
x = Box::new("Hi");
}
然而,C# docs state:
在编译时,假定键入为动态的元素支持任何操作。
特质对象不是这样;特征对象只能用于特征中的显式方法。我没有发现这是我编写的代码中的一个重大障碍。通常,我想调用固定数量的方法,因此可以将这些方法映射到特征。在其他情况下,我可以提供一个通用类型,以允许用户指定适合其案例的类型。