Rust 中返回多种类型的惯用方式

Pet*_*sen 5 polymorphism parsing rust

我正在编写一个解析多个文件的程序。这些文件可以分为许多不同的类别,但我事先并不知道是哪个类别。我为文件可以包含的每种数据类型创建一个类型是有意义的,但我正在努力将该数据类型从我的解析器中取出并放入我的模型/主程序中。

在大多数其他编程语言中,我可能会定义一个函数/方法,它接受文件名作为输入,并返回通用类型作为输出。然后,根据我的需要,我将强制转换或测试通用返回类型的类型,并获取重新调整数据的真实类型。

然而,这在 Rust 中似乎并不起作用。我可以定义一个返回 Trait 的函数,如下所示:

fn parse_file(file: &'str) -> impl ParsedData
Run Code Online (Sandbox Code Playgroud)

其中ParsedData是我所有数据类型的共同特征。但从这里我该怎么办呢?在某些时候,我需要分离隐藏在 ParsedData Trait 后面的不同类型的数据。

解决方案 1:我发现 Any 特征确实可以将特征向下转换为类型。但普遍的共识似乎是你应该避免这种情况。我不确定我是否完全理解为什么人们不喜欢它,但如果没有其他事情,它似乎需要相当多的工作/样板代码才能工作。

解决方案 2:还可以将所有已知数据类型填充到一个大容器类型中,如下所示:

pub struct DataContainer {
    pub data_type_1: Option<DataType1>,
    pub data_type_2: Option<DataType2>,
    pub data_type_3: Option<DataType3>,
    pub data_type_4: Option<DataType4>,
}

fn parse_file(file: &'str) -> DataContainer 
Run Code Online (Sandbox Code Playgroud)

然后将其传递下去,直到您需要其中的数据类型为止。

解决方案 n:似乎有许多不太受欢迎的解决方案


在事先不知道类型的情况下读取一些数据肯定是一个非常常见的任务。难道就没有一个切实可行的办法来应对吗?我读过好几次,Rust 中的向下转型支持很差的主要原因是因为有其他更好的方法来处理人们遇到需要向下转型数据的几乎/每一种类型的问题。

这是我的问题。如何以简单、惯用的方式处理这个问题?

问题定义:

  • 假设您想读取多个文件。有些将包含用户个人资料,有些将包含图片(不与用户绑定),有些将包含烹饪食谱。
  • 在阅读文件之前你并不知道它包含什么,但它很容易解析并且不存在不确定性。
  • 我在上面定义了一个函数parse_file,但这只是我认为这将是读取这些文件的一个很好的界面,因为它们可能共享很多用于打开文件等的代码。

小智 5

你想要的是一个枚举

如果您有类型DataType1DataType2和,DataType3DataType4可以定义一个保证仅包含其中一种数据类型的枚举。

enum DataContainer {
    Type1(DataType1),
    Type2(DataType2),
    Type3(DataType3),
    Type4(DataType4),
}
Run Code Online (Sandbox Code Playgroud)

然后您可以使用以下方法处理每个变体match

let data: DataContainer = parse(something);
match data {
    Type1(x) => do_something_with_type_1(x),
    Type2(x) => do_something_with_type_2(x),
    Type3(x) => do_something_with_type_3(x),
    Type4(x) => do_something_with_type_4(x),
}
Run Code Online (Sandbox Code Playgroud)