我可以使用strum将字符串转换为f64吗?

时间:2018-11-11 22:43:13

标签: rust

我正在重构我编写的small stack based language,并决定将解析器阶段与执行阶段分开,因此我将字符串解析为Token枚举。我尝试使用strum来执行此操作,这是我可以管理的最小示例:

extern crate strum; // 0.11.0
#[macro_use]
extern crate strum_macros; // 0.11.0

#[derive(EnumString)]
enum Token {
    #[strum(default="true")]
    Number(f64)
}

fn main() {
}

基本上,如果没有匹配项,应该执行的操作是默认解析语法。因此,在这种情况下,请转换为浮点数。哪个给了:

error[E0277]: the trait bound `f64: std::convert::From<&str>` is not satisfied
 --> src/main.rs:5:10
  |
5 | #[derive(EnumString)]
  |          ^^^^^^^^^^ the trait `std::convert::From<&str>` is not implemented for `f64`
  |
  = help: the following implementations were found:
            <f64 as std::convert::From<u32>>
            <f64 as std::convert::From<i32>>
            <f64 as std::convert::From<f32>>
            <f64 as std::convert::From<i8>>
          and 3 others
  = note: required because of the requirements on the impl of `std::convert::Into<f64>` for `&str`

我还尝试添加impl进行转换:

extern crate strum;
#[macro_use]
extern crate strum_macros;

impl<'a> From<&'a str> for f64 {
    #[inline]
    fn from(s: &'a str) -> Self {
        // See footnote [1] for why conversion is done this way.
        s.parse::<f64>().unwrap_or(0.0).to_owned();
    }
}

#[derive(EnumString)]
enum Token {
    #[strum(default="true")]
    Number(f64)
}

fn main() {
}

但是,这给出了:

error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
 --> src/main.rs:5:1
  |
5 | impl<'a> From<&'a str> for f64 {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
  |
  = note: the impl does not reference any types defined in this crate
  = note: define and implement a trait or new type instead

因为我使用了strum,所以无法将其放在Rust Playground上,但是Cargo.toml是:

[package]
name = "strum_test"
version = "0.1.0"

[dependencies]
strum = "0.11.0"
strum_macros = "0.11.0"

我编辑的文件位于strum_test/src/main.rs中。是否有办法处理strum中的这种行为,或者至少还有另一种优美的方式来处理从&strenum Token的这种转换?


1在设计语言上,很难犯错误。例如,将"lol"转换为0是否有意义?并非如此,但是我的语言仍然可以做到。在CodeReview链接中提供了更多信息。

1 个答案:

答案 0 :(得分:1)

基于Sven Marnach的评论,我添加了struct Float(f64)。这是所有代码供参考:

extern crate strum;
#[macro_use]
extern crate strum_macros;

struct Float(f64);

impl<'a> From<&'a str> for Float {
    #[inline]
    fn from(s: &'a str) -> Self {
        Float(s.parse::<f64>().unwrap_or(0.0).to_owned())
    }
}

#[derive(EnumString)]
enum Token {
    #[strum(default="true")]
    Number(Float)
}

fn main() {
}