是否可以在Rust中使用多种类型进行模式匹配?

时间:2016-11-10 23:03:55

标签: pattern-matching rust

好像你不能。如果没有,是否有计划支持添加它或运行时类型信息(RTTI)?

struct Bus;
struct Car;
struct Person;

fn main() {
    let x = Bus;
    //or more realistically, let x = function_with_multiple_return_types();

    match x {
        Car => {
            // ...
        }
        Bus => {
            // this gets executed
        }
        Person => {
            // ...
        }
    }
}

这个例子很简单。在现实生活中,只有x可以是多种类型才有用。例如let x = function_with_multiple_return_types();

2 个答案:

答案 0 :(得分:5)

没有人能够100%准确地说某项功能将会或不会永远实施,但我可以100%相信这绝不会实现。

为什么?因为提出的语法没有任何好处。 Rust是静态类型的语言。这意味着编译器知道变量的类型。除Bus之外的任何分支都不会被执行。变量不可能有多种类型!为什么语言会改变以允许您添加永远不会被使用的代码?这不会很有用。

匹配语句和模式匹配通常只有在存在多种可能的变体时才有用。这就是Rust有enum s的原因;允许一组固定的动态选择(a.k.a。在运行时制作)。

如果你需要一套开放的动态决策,那就是特质(也许是专业化)。甚至还有一个特征允许any concrete type

作为mentioned in the comments,您可以使用Any提供的特质对象向下转换,但无法使用match

另见:

答案 1 :(得分:1)

查看std::any::Any和Andrew Johnson的链接。我认为你可以使用Any做一些接近你想做的事情。 fn get_type_id(&self) -> TypeId仅在夜间版本中,所以如果你有稳定版本的Rust,你可能还无法使用它。

This示例已接近您想要的内容,仅使用if let代替match

我写了三个例子来演示如何实现这一点,虽然没有一个可以用match遗憾地找到它们......可以找到它们并运行here。以下是我最喜欢的方式:

fn run_example_one() {
    let unknown_type = gen_rand_any();

    if let Some(string) = unknown_type.downcast_ref::<String>() {
       println!("It's a string!");
    } else if let Some(my_struct) = unknown_type.downcast_ref::<MyStruct>() {
        println!("my struct! name = {:?}", my_struct.my_name);
    } else if let Some(int) = unknown_type.downcast_ref::<i32>() {
       println!("something singed 32 bit int.");
   }
}