我想写一个macro_rules!宏,它的参数是一个,ident并且是字符串文字列表。宏的扩展需要同时包含字符串文字和相应的字节文字。该宏用于测试,将仅与仅包含U + 0000 ... U + 007F范围内的字符的字符串一起使用。如果将字符串文字以外的任何内容提供给宏会导致编译时错误,则可以。
如果当前无法不使用过程宏来实现,请告诉我,不要费心实际编写过程宏;-)
所需的调用和扩展是这样的:
all_s! isalpha [ "abcdefghijklmnopqrstuvwxyz" /* , ... */ ];
Run Code Online (Sandbox Code Playgroud)
=>
assert!(isalpha("abcdefghijklmnopqrstuvwxyz"));
assert!("abcdefghijklmnopqrstuvwxyz".chars().all(|b| isalpha(b));
assert!(isalpha(b"abcdefghijklmnopqrstuvwxyz"));
assert!(b"abcdefghijklmnopqrstuvwxyz".iter().all(|b| isalpha(b)));
/* ... */
Run Code Online (Sandbox Code Playgroud)
据我所知:
macro_rules! all_s {
($what: ident, $( $str: tt ),* ) => {{
$(
assert!($what($str));
assert!($str.chars().all(|b| $what(b));
assert!($what(BYTE_LITERAL!($str)));
assert!(BYTE_LITERAL!($str).iter().all(|b| $what(b)));
)*
}}
}
Run Code Online (Sandbox Code Playgroud)
但是我不知道该说什么BYTE_LITERAL!,而且我也收到错误消息,提示我没有正确编写匹配模式,例如“ macro all_s!期望没有ident参数,给定'isalpha'” “ $ what:ident”就在那里。
我也不知道如何拒绝
tt不是字符串文字的。
如果您利用参数是字符串这一事实,那么类型检查器将负责产生错误。
macro_rules! all_s {
($what: ident, $( $str: tt ),* ) => {{
$(
assert!($what($str));
assert!(str::chars($str).all(|c| char::is_alphabetic(c)));
assert!(str::chars($str).all(|c| char::is_alphabetic(c)));
)*
}}
}
Run Code Online (Sandbox Code Playgroud)
在您的问题代码中,您尝试将相同的isalpha值与char和的值一起使用u8。您必须首先将chars 转换为s:u8
assert!(str::chars($str)
.map(|c| c as u8) // this is safe given the assumption you stated
.all(|b| b < 0x7F));
Run Code Online (Sandbox Code Playgroud)