繁体   English   中英

在 Rust 中,我可以在没有宏的情况下将字符串转换为枚举吗?

[英]Can I convert a string to enum without macros in Rust?

例如,如果我有这样的代码:

enum Foo {
    Bar,
    Baz,
    Bat,
    Quux
}

impl Foo {
    from(input: &str) -> Foo {
        Foo::input
    }
}

这显然会失败,因为input不是 Foo 的方法。 我可以手动输入:

from(input: &str) -> Foo {
    match(input) {
        "Bar" => Foo::Bar,
        // and so on...
    }
}

但我没有得到自动便利。

为了这个特定目的,Java 似乎在枚举上有一个字符串查找功能

是否可以在不编写自己的宏或从板条箱中导入宏的情况下获得它?

编辑:答案是否定的。 Rust 不提供反射,通常使用#[derive]来处理这类任务。

您可以使用板条箱enum_derivecustom_derive来做您想做的事。

这是一个例子:

#[macro_use]
extern crate custom_derive;
#[macro_use]
extern crate enum_derive;

custom_derive! {
    #[derive(Debug, EnumFromStr)]
    enum Foo {
        Bar,
        Baz,
        Bat,
        Quux
    }
}

fn main() {
    let variable: Foo = "Bar".parse().unwrap();
    println!("{:?}", variable);
}

自定义EnumFromStrderive允许您使用parse方法来获取Foo

你应该实现std::str::FromStr特性。

use std::str::FromStr;

#[derive(Debug, PartialEq)]
enum Foo {
    Bar,
    Baz,
    Bat,
    Quux,
}

impl FromStr for Foo {

    type Err = ();

    fn from_str(input: &str) -> Result<Foo, Self::Err> {
        match input {
            "Bar"  => Ok(Foo::Bar),
            "Baz"  => Ok(Foo::Baz),
            "Bat"  => Ok(Foo::Bat),
            "Quux" => Ok(Foo::Quux),
            _      => Err(()),
        }
    }
}



fn main() {
    // Use it like this
    let f = Foo::from_str("Baz").unwrap();
    assert_eq!(f, Foo::Baz);
}

代码生成(又名自动便利)和反射通常需要付出代价。 在实践中,您不太可能最终得到多个枚举变体。

操场上奔跑

与其他答案相同的免责声明:“没有宏”是不可能的。

扩展最高投票的答案。 该线程中所述, custom_derive + enum_derive的组合有些过时。 现代 Rust 不再需要基于custom_derive的解决方案。

一个现代的替代品是strum 用法可能如下所示:

use strum_macros::EnumString;
use std::str::FromStr;

#[derive(EnumString)]
enum Foo {
    Bar,
    Baz,
    Bat,
    Quux
}

fn example_usage(input: &str) -> Foo {
    Foo::from_str(input).unwrap()
}

注意:您同时需要strumstrum_macrosCargo.toml

strum还为字符串表示提供了一些很好的灵活性。 文档

请注意,默认情况下FromStr的实现仅匹配变体的名称。 有一个选项可以通过#[strum(serialize_all = "snake_case")]类型属性匹配不同的大小写转换。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM