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

标签 parsing rust polymorphism

这个问题在这里已经有了答案:





Multiple return types from a method

(1 个回答)


1年前关闭。




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

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

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

fn parse_file(file: &'str) -> impl ParsedData

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

解决方案一:我发现 Any trait 确实可以将 Trait 向下转换为类型。但普遍的共识似乎是,这是你应该避免的事情。我不确定我是否完全理解人们为什么不喜欢它,但如果没有别的,它似乎需要大量的工作/样板代码才能开始工作。

方案二:也有可能将所有已知的数据类型填充到一个大容器类型中,如下所示:
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 

并且只是传递它,直到您需要其中的数据类型。

解决方案 n:似乎有一些不太受欢迎的解决方案

在事先不知道类型的情况下读取一些数据肯定是一件很常见的工作。难道没有事实上的方法来处理它吗?我读了好几遍,Rust 中向下转换支持不佳的主要原因是由于存在其他更好的方法来处理人们遇到需要向下转换数据的几乎/每一种类型的问题。

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

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

    你想要的是一个enum .

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

    enum DataContainer {
        Type1(DataType1),
        Type2(DataType2),
        Type3(DataType3),
        Type4(DataType4),
    }
    

    然后您可以使用 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),
    }
    

    关于parsing - 在 Rust 中返回多种类型的惯用方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60336781/

    相关文章:

    rust - 如何使用 Rust 和 web-sys 将 Clamped<Vec<u8>> 转换为 Clamped<&mut [u8]> ?

    rust - Rust 中是否有一个有效的函数可以找到排序向量中某个值第一次出现的索引?

    windows - 如何在 Windows 开发环境中使用 OpenSSL for Rust

    Django - 多态模型还是一个大模型?

    generics - 为什么泛型父类(super class)型声明不允许引用子类型对象?

    java - 我可以从 super 的 super 调用重写的方法吗?

    javascript - 从解析树到 NFA

    c - c中的字符串解析和子字符串

    Python 在使用 Usecol 时添加列

    algorithm - 提高单词匹配(向前看?)算法性能