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

11

看起来好像你不能这样做。如果不行,是否有计划支持它或者运行时类型信息(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();


我不熟悉 Rust,但我认为每个 match 子句需要是相同类型的。尝试将它们都作为同一个超类/接口的一部分。 - Carcigenicate
你可以尝试使用类似于这个例子中的标记联合体(tagged union)来实现最接近的效果。链接 - squiguy
2个回答

9
没有人能以100%的准确度说一个功能将会或不会被实现,但我可以百分之百肯定地说,这个功能永远不会被实现。为什么呢?因为提议的语法没有任何好处。 Rust是一种静态类型的语言。这意味着编译器知道变量的类型。除了“Bus”以外,没有任何分支会被执行。变量不可能有多个类型!为什么要改变语言来允许您添加永远不会使用的代码?那没什么用。匹配语句和模式匹配通常只在存在多个可能的变体时才有用。这就是Rust拥有枚举的原因; 允许一个固定的动态选择集(也称为运行时选择)。如果您需要一个开放的动态决策集,则可以使用特性(也许是专业化)。甚至有一个特性允许任何具体类型

正如评论中提到的那样,您可以使用由Any提供的特质对象下转换,但无法使用match

另请参见:


我的问题是受我编写的Racket解释器启发,其中Match可以在不同类型之间进行分支。当然,Lisp是动态类型的,所以在Rust中这通常没有用。我感觉可能有一些特殊情况,动态返回函数类型可能会有用(虽然不是惯用法)- std::any似乎大多数情况下都可以满足这种用例。谢谢! - randyrand
1
Lisp 是动态类型语言,这就是我最初困惑的原因。 - randyrand
返回类型动态地——但即使如此,您也希望对这些返回的类型进行操作。这意味着有一组方法您想要能够调用;这就是特质的含义。它可以作为特质对象返回。 - Shepmaster
我认为甚至可以实现类似于Scala类型安全的鸭子类型的功能。这是一条不同于向下转型的路线,但仍然很有趣。 - ArtemGr
问题在于编译器可能知道确切的类型,但用户在使用宏时不知道它/没有办法表达它。由于宏可以返回任何类型,并且宏无法进行任何类型检查,因此唯一的检查方式是通过编译器解决的条件。 - Luxalpa
显示剩余3条评论

1

查看std::any::Any和Andrew Johnson的链接。我认为您可以使用Any实现接近您想要的内容。但是,fn get_type_id(&self) -> TypeId仅适用于夜间构建版本,因此如果您使用稳定版本的Rust,则可能无法使用它。

这个示例与您想要的接近,只是使用if let而不是match

我写了三个示例来演示如何实现这一点,但可惜的是没有一个可以与match一起使用...它们可以在这里找到并运行。以下是我最喜欢的方法:

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.");
   }
}

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