下面的C#代码可以转换为Rust吗?在C#中是否存在与“dynamic”相当的Rust?
dynamic x = 109;
x = "Hi";
我想要一个通用的动态类型来允许创建一个动态值的数组。例如:
var l = new dynamic[2];
l[0] = 102;
l[1] = "Hi";
下面的C#代码可以转换为Rust吗?在C#中是否存在与“dynamic”相当的Rust?
dynamic x = 109;
x = "Hi";
我想要一个通用的动态类型来允许创建一个动态值的数组。例如:
var l = new dynamic[2];
l[0] = 102;
l[1] = "Hi";
一种选择是使用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
)中定义的操作。向下调用是需要调用具体类型的任何方法。
我认为这是不可能的类型如C#锈的dynamic
。为了支持在动态值上调用任何方法,必须具有(完整的)运行时反射支持,而Rust不提供它。
如果您知道将要调用的方法,那么最好的选择是定义一个特征并使用Box<Trait>
(在这种情况下不需要Any
)。
啊,我正要用这个更新。请注意,您不能向下转换为特性对象,因此您无法获得“任何可打印的类型”,例如。仍然不匹配'动态',因为你不能只调用任何任意方法。 – Shepmaster
不是直接。你可以创建一个新的绑定为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:
在编译时,一个元件假定输入为动态,以支持任何操作。
对于特质对象这不是真的;特征对象只能用于特征中的显式方法。我没有发现这是我写的代码中的一个重大障碍。一般来说,我想调用的方法数量是固定的,因此可以将这些方法映射到特征。在其他情况下,我可以提供一个通用类型来允许用户指定一种适合他们情况的类型。
您的编辑将使它成为[创建异构对象集合的最佳方法是什么?]的副本(http://stackoverflow.com/questions/27957103/what-is-the-best-way-to -create-A-异构收集-的对象)。 – Shepmaster
你真的需要允许任何类型,或只是一个封闭的类型联合(例如'int'或'string')吗? – Lee
@Lee任何类型... – TuxCopter