这个maplit板条箱允许哈希图文字作为=>分隔符。我相信不可能使用macro_rules!分隔:符,但是可以使用处理令牌流的宏吗?
是否不可能将{ key: value }样式宏添加到语言中,即使在编译器中也是如此?
我怀疑问题与:类型运算符冲突,但我无法构建一个不明确的示例,其中编译器无法决定以哪种方式解释:.
@kmdreko 很好地解释了为什么宏中不能有一个表达式后跟一个冒号。但是,您可以通过强制键为令牌树而不是表达式来解决这个问题:
macro_rules! hashmap{
( $($key:tt : $val:expr),* $(,)? ) =>{{
#[allow(unused_mut)]
let mut map = ::std::collections::HashMap::with_capacity(hashmap!(@count $($key),* ));
$(
#[allow(unused_parens)]
let _ = map.insert($key, $val);
)*
map
}};
(@replace $_t:tt $e:expr ) => { $e };
(@count $($t:tt)*) => { <[()]>::len(&[$( hashmap!(@replace $t ()) ),*]) }
}
Run Code Online (Sandbox Code Playgroud)
与可能可以很好地处理这种模式的过程宏相反,采用此路线的缺点是大多数复杂的表达式必须用括号或大括号括起来。例如,
let map = hashmap!{ 2 + 2 : "foo" };
Run Code Online (Sandbox Code Playgroud)
行不通,但是
let map = hashmap!{ (2 + 2) : "foo" };
Run Code Online (Sandbox Code Playgroud)
将要。