2016-07-05 29 views
4

下面的C#代码可以转换为Rust吗?在C#中是否存在与“dynamic”相当的Rust?

dynamic x = 109; 
x = "Hi"; 

我想要一个通用的动态类型来允许创建一个动态值的数组。例如:

var l = new dynamic[2]; 
l[0] = 102; 
l[1] = "Hi"; 
+0

您的编辑将使它成为[创建异构对象集合的最佳方法是什么?]的副本(http://stackoverflow.com/questions/27957103/what-is-the-best-way-to -create-A-异构收集-的对象)。 – Shepmaster

+0

你真的需要允许任何类型,或只是一个封闭的类型联合(例如'int'或'string')吗? – Lee

+0

@Lee任何类型... – TuxCopter

回答

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) 
     } 
    } 
} 

需要注意的是,违背dynamicC#,假定支持任何操作,AnyBox<Any>)类型的值仅支持在AnyBox<Any>Any)中定义的操作。向下调用是需要调用具体类型的任何方法。


我认为这是不可能的类型如C#锈的dynamic。为了支持在动态值上调用任何方法,必须具有(完整的)运行时反射支持,而Rust不提供它。

如果您知道将要调用的方法,那么最好的选择是定义一个特征并使用Box<Trait>(在这种情况下不需要Any)。

+0

啊,我正要用这个更新。请注意,您不能向下转换为特性对象,因此您无法获得“任何可打印的类型”,例如。仍然不匹配'动态',因为你不能只调用任何任意方法。 – Shepmaster

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

在编译时,一个元件假定输入为动态,以支持任何操作。

对于特质对象这不是真的;特征对象只能用于特征中的显式方法。我没有发现这是我写的代码中的一个重大障碍。一般来说,我想调用的方法数量是固定的,因此可以将这些方法映射到特征。在其他情况下,我可以提供一个通用类型来允许用户指定一种适合他们情况的类型。

相关问题