如何在Rust中获取结构体字段名?

19

是否有类似于JS的Object.keys()在Rust中的struct的等效物?

我需要一些东西从结构字段名称生成CSV标题(我使用rust-csv)。

struct Export {
    first_name: String,
    last_name: String,
    gender: String,
    date_of_birth: String,
    address: String
}

//... some code

let mut wrtr = Writer::from_file("/home/me/export.csv").unwrap().delimiter(b'\t');

wrtr.encode(/* WHAT TO WRITE HERE TO GET STRUCT NAMES as tuple of strings or somethings */).is_ok()

你不能在没有 rustc 插件(仅在 Nightly 版本上运行)的情况下这样做。 - mcarton
3
您不太可能需要编译器插件来满足您的实际用例;如存储库中所述,可以使用 #[derive(RustcDecodable)]。尽管如此,这并没有回答您正在询问的问题,即列出 任何 结构体字段名称的通用方法。这是一个典型的XY问题。 - Shepmaster
1
这也可以通过实现自己的过程宏来完成,其中你解析AST并为你的结构创建一个特质实现,该实现返回字段名称。我个人在2周前已经完成了这个过程,但代码不是公开的,而且这个问题已经关闭了。所以只是让你知道这是可能的,通过一些#[derive(Introspection)] - Victor Polevoy
1
@AlexanderArutinyants,我会在一周内公开它。如果您对此解决方案感兴趣,我可以在这里告诉您何时发生(只需将#[derive(Introspection)]添加到枚举或结构体即可)。 - Victor Polevoy
@AlexanderArutinyants 在这里。希望这可以帮到你。我还没有提供足够的文档,但你已经可以使用它了。我计划在未来扩展它的功能,但有些事情是不可能做到的 :( - Victor Polevoy
显示剩余5条评论
1个回答

30

Rust目前的元编程主要方法是 通过宏。在这种情况下,您可以捕获所有字段名称,然后添加一个返回它们字符串形式的方法:

macro_rules! zoom_and_enhance {
    (struct $name:ident { $($fname:ident : $ftype:ty),* }) => {
        struct $name {
            $($fname : $ftype),*
        }

        impl $name {
            fn field_names() -> &'static [&'static str] {
                static NAMES: &'static [&'static str] = &[$(stringify!($fname)),*];
                NAMES
            }
        }
    }
}

zoom_and_enhance!{
struct Export {
    first_name: String,
    last_name: String,
    gender: String,
    date_of_birth: String,
    address: String
}
}

fn main() {
    println!("{:?}", Export::field_names());
}

要了解高级宏,请务必查看The Little Book of Rust Macros


2
类似的问题和解决方案:https://dev59.com/8V0a5IYBdhLWcg3wva56#29986760 - melak47
1
@melak47 很好的观点!你认为这个问题应该标记为重复吗? - Shepmaster
你能优化一下吗?等一下,我来优化一下。 - jayphelps
似乎我无法在这里添加答案,所以我在其他链接的问题上进行了回答。我的额外复杂性是我还需要#[derive()]宏来处理结构体,因此这里的解决方案与此不兼容。我对解决方法的记录在这里: https://dev59.com/8V0a5IYBdhLWcg3wva56#73375434 - dlaehnemann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接