在C#中是否有一个相当于`dynamic`的Rust?

时间:2016-07-05 18:44:47

标签: dynamic rust

可以将以下C#代码转换为Rust吗?

dynamic x = 109;
x = "Hi";

我要求使用通用动态类型来创建动态值数组。例如:

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

2 个答案:

答案 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#相反,假设支持任何操作,类型AnyBox<Any>)的值仅支持在AnyBox<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

  

在编译时,假定键入为动态的元素支持任何操作。

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