在Rust中是否有与C#中的“dynamic”相当的东西?

4
以下的C#代码能够翻译成Rust吗?
dynamic x = 109;
x = "Hi";

我希望您能创建一个通用的动态类型,以允许创建包含动态值的数组。例如:
var l = new dynamic[2];
l[0] = 102;
l[1] = "Hi";

您的编辑将使此问题成为什么是创建异构对象集合的最佳方法?的重复。 - Shepmaster
你实际上需要允许任何类型,还是只需要一组封闭的类型(例如 intstring)? - Lee
2个回答

4

一种选择是使用Any的向量(链接到beta,因为稳定文档没有显示定义为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)
        }
    }
}

请注意,与在 C# 中的 dynamic 不同,被认为支持任何操作,类型为 Any 的值(Box)仅支持在 Any(Box 和 Any)中定义的操作。必须进行向下转换才能调用具体类型的任何方法。
我认为,在 Rust 中不可能像 C# 中的 dynamic 一样拥有这样的类型。为了支持在动态值上调用任何方法,需要完整的运行时反射支持,而 Rust 并没有提供它。
如果您知道要调用的方法,则最佳选择是定义一个 trait,并使用 Box(在这种情况下不需要使用 Any)。

啊,我正要更新这个。请注意,您无法向下转换为特质对象,因此您无法获得“任何可打印的类型”,例如。仍然不匹配dynamic,因为您不能只调用任意方法。 - 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#文档指出:

在编译时,被声明为动态类型的元素预设支持任何操作。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接