[英]Can you use an optional argument in a rust macro without syntax variables?
在 rust 宏$(...)?
我希望能夠改變結構的制定方式。 例如:
struct Field<T>(T);
struct OptionalField<T>(T);
define_struct!(StructName => {
field_one: i32,
field_two?: i32
});
// would ideally evaluate to
struct StructName {
field_one: Field<i32>,
field_two: OptionalField<i32>
}
編寫帶有重復部分的宏並不是困難的部分,但給我帶來麻煩的部分是如何使可選問號更改用作結構字段類型的類型。 到目前為止,我已經嘗試過:
macro_rules! define_struct {
($name:ident => {
$($field_name:ident$(?)?: $type:ty),*
}) => {
struct $name {
$($field_name: $(Optional)?Field<$type>),*
}
};
}
宏調用很好,並且遵循定義的模式,但是在Field
標識符之前插入Optional
是困難的。 $(Optional)?
拋出錯誤:
attempted to repeat an expression containing no syntax variables matched as repeating at this depth
|
| $($field_name: $(Optional)?Field<$type>),*
| ^^^^^^^^^^
有沒有辦法根據可選宏模式的存在插入關鍵字而不必使用語法變量?
您可以通過增量tt
muncher和下推累積來做到這一點:
macro_rules! define_struct {
(@fields $name:ident { $($fields:tt)* } $field_name:ident?: $type:ty, $($rest:tt)*) => {
define_struct!(@fields
$name {
$($fields)*
$field_name: OptionalField<$type>,
}
$($rest)*);
};
(@fields $name:ident { $($fields:tt)* } $field_name:ident: $type:ty, $($rest:tt)*) => {
define_struct!(@fields
$name {
$($fields)*
$field_name: Field<$type>,
}
$($rest)*);
};
(@fields $name:ident { $($fields:tt)* }) => {
struct $name { $($fields)* }
};
($name:ident => { $($fields:tt)* }) => {
define_struct!(@fields $name {} $($fields)*);
};
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.