动态推断字符串的类型

时间:2015-11-07 00:42:29

标签: rust

Rust新手在这里。在给定字符串的情况下动态推断最可能类型的最佳方法是什么?我试图编写一个函数,给定一个字符串返回最可能的类型,但我不知道从哪里开始。在Python中,我可能会使用try-except块。这是我期望的:

"4" -> u32 (or u64)
"askdjf" -> String
"3.2" -> f64

等等?我知道有些字符串可以分配给几种可能的类型,所以问题没有明确定义,但我只对如何有效解决问题的一般理念感兴趣。

2 个答案:

答案 0 :(得分:8)

字符串切片(&str)上有一个parse方法,它尝试将字符串解析为特定类型。但是,你必须知道你准备好处理的具体类型。 parse方法可以返回实现FromStr的任何类型的值。

fn main() {
    if let Ok(i) = "1".parse::<u32>() {
        println!("{}", i);
    }
    if let Ok(f) = "1.1".parse::<f64>() {
        println!("{}", f);
    }
}

请注意,::<T>部分仅在编译器无法推断您要解析的类型时才需要(在这种情况下您将遇到编译器错误)。

答案 1 :(得分:5)

  

我正在尝试编写一个函数,给定一个字符串返回最可能的类型,但我不知道从哪里开始。

首先:Rust是静态类型的,这意味着一个函数只返回一个类型,因此你不能只返回不同的类型,比如动态类型语言。但是,有一些方法可以模拟动态类型 - 即两个(我能想到的):

  1. enum:如果您拥有固定数量的可能类型,则可以为每个类型定义一个enum变体,如下所示:

    enum DynType {
        Integer(i64),
        Float(f32),
        String(String),
    }
    
    fn dyn_parse(s: &str) -> DynType {
        ...
    }
    

    您可以在this以及以下Rust书章中的enum上阅读更多内容。

  2. 标准库中有一个特性用于模拟动态类型:Any。有更多信息here。您的代码可能如下所示:

    fn dyn_parse(s: &str) -> Box<Any> {
        ...
    }
    

    您不能直接返回特征对象,因此您必须将其放在Box

  3. 请注意,这两种可能性都要求您的功能用户进行额外的调度。由于Rust是静态类型的,因此您无法以动态类型语言执行习惯操作。

    也许你应该尝试以一种在静态类型世界中更有意义的不同方式来解决你的问题。

    关于实现部分:像FrancisGagné所说,有parse试图将字符串解析为程序员指定的类型。您当然可以将这些parse次呼叫链接到不同的类型,并取得第一个成功的呼叫。但这可能不是你想要的,也许不是最快的实现。

    当然,您应该首先考虑确切的规则,字符串应该解析为什么类型。之后,您可以构建一个检测字符串类型的有限状态机。正确地做到这一点可能有点棘手。