rust - 将字符串转换为 Vec在编译时进行模式匹配
问题描述
我正在用 Rust 编写解析器,并且正在从Vec<char>
. 目前,我的代码看起来像
match &source[..] {
['l', 'e', 't', ..] => ...,
['t', 'r', 'u', 'e', ..] => ...,
_ => ...
}
显然,这比我想要的要冗长得多,而且不容易阅读。有什么方法可以在编译时转换"let"
为['l', 'e', 't']
(使用宏或 const 函数)以便像这样对其进行模式匹配?
解决方案
我不认为你可以使用 Rust 标准库中的宏来做到这一点,但你可以编写自己的宏:
use proc_macro::{TokenStream, TokenTree, Group, Delimiter, Punct, Literal, Spacing};
use syn::{parse_macro_input, LitStr};
#[proc_macro]
pub fn charize(input: TokenStream) -> TokenStream {
// some stuff for later
let comma_token = TokenTree::Punct(Punct::new(',', Spacing::Alone));
let rest_token_iterator = std::iter::once(TokenTree::Punct(Punct::new('.', Spacing::Joint))).chain(std::iter::once(TokenTree::Punct(Punct::new('.', Spacing::Alone))));
let string_to_charize: String = parse_macro_input!(input as LitStr).value();
let char_tokens_iterator = string_to_charize.chars().map(|char| TokenTree::Literal(Literal::character(char)));
// if you are on nightly, Iterator::intersperse() is much cleaner than this (https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.intersperse)
let char_tokens_interspersed_iterator = char_tokens_iterator.map(|token| [comma_token.clone(), token]).flatten().skip(1);
let char_tokens_interspersed_with_rest_iterator = char_tokens_interspersed_iterator.chain(std::iter::once(comma_token.clone())).chain(rest_token_iterator);
std::iter::once(TokenTree::Group(Group::new(Delimiter::Bracket, char_tokens_interspersed_with_rest_iterator.collect()))).collect()
}
宏在行动:
match &['d', 'e', 'm', 'o', 'n', 's', 't', 'r', 'a', 't', 'i', 'o', 'n'][..] {
charize!("doesn't match") => println!("Does not match"),
charize!("demo") => println!("It works"),
charize!("also doesn't match") => println!("Does not match"),
_ => panic!("Does not match")
}
请注意,这是一个程序宏,因此必须存在于proc_macro
crate 中。
推荐阅读
- android - Android NDK - 执行 .so 返回 0 但不工作
- pandas - 使用 Dask 进行基于日期时间索引的切片
- java - Apache Camel 如何通过 SFTP 支持 ASCII 模式文件传输?
- java - 在第一次启动应用程序时询问 MediaProjection 权限并存储 MediaProjectionManager 实例以供以后使用
- html - HTML&CSS 调节内容高度
- javascript - npm 复制脚本在 Windows 8.1 上不起作用
- javascript - Vue 依赖在本地的行为与 npm 不同
- r - 具有多个调解员的因果调解包
- json - 在 Laravel 中获取帖子的正文内容
- python - 连接多个 Pandas 数据帧时出现内存错误