< 返回版块

hzqd 发表于 2021-12-28 15:26

大家好,我最近写了一个声明宏。但我对 泛型dyn关键字trait 使用什么片段说明符(fragment-specifier)感到困惑。

我尝试使用 tt 来指定它们,虽然只编译宏通过,但使用时发生编译错误:

error: local ambiguity when calling macro `struct_new`: multiple parsing options: built-in NTs tt ('limit') or 1 other option. 

解析 < 会导致此错误。

我的这个宏是为了简化结构体的创建和它的初始化 new() 关联函数。

这是完整的宏代码和用例:

macro_rules! struct_new {
    ($vis:vis struct $s_name:ident;) => {$vis struct $s_name;};

    ($(#[$attr:meta])* $vis:vis struct $s_name:ident $(<$($generic:tt),*>)? $(($($p_vis:vis $p_name:ident: $p_type:ty),* $(,)?))? $(where $($id:tt: $($limit:tt $(<$dyn:tt $traits:tt $(($($t:tt),*) $(-> ($($r:tt),*))?)?>)?)+*),*)? {
        $($field_vis:vis $field:ident: $type:ty = $val:expr),* $(,)?
    }
    $($tail:tt)*) => {
        $(#[$attr])*
        $vis struct $s_name $(<$($generic),*>)? $(where $($id: $($limit $(<$dyn $traits $(($($t),*) $(-> ($($r),*))?)?>)?)+*),*)? {
            $($($p_vis $p_name: $p_type,)*)?
            $($field_vis $field: $type),*
        }
        impl $(<$($generic),*>)? $s_name $(<$($generic),*>)? $(where $($id: $($limit $(<$dyn $traits $(($($t),*) $(-> ($($r),*))?)?>)?)+*),*)? {
            fn new($($($p_name: $p_type),*)?) -> Self {
                $s_name {
                    $($($p_name,)*)?
                    $($field: $val),*
                }
            }
        }
        struct_new! {
            $($tail)*
        }
    };

    () => {}
}

struct_new!(
    #[derive(Debug)]
    pub struct A<'a, T, R>(foo: T, pub bar: &'a str,) where T: Box<dyn FnOnce(T) -> R> {
        pub  abc: u8 = 255,
        xyz: &'a str = "xyz",
    }
    struct B {}
    struct C;
);

评论区

写评论
苦瓜小仔 2022-01-02 02:14

我用过程宏做到了类似的功能(语法使用上不完全一样):struct_new2-multi.rs

https://github.com/zjp-CN/structs_new

苦瓜小仔 2021-12-28 17:47

想要简便的匹配方式,用 ty 分类符,但是在你的例子里不行,理由如下:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=bddd4fe5776be6ffeb1fc6abae68a1ff

简短地说,$($t:tt)* 捕获的内容会超出你所控制的范围,让你期望范围之外的标记捕获进来,而且

一旦语法分析器开始消耗标记以匹配某捕获,整个过程便 无法停止或回溯

via The Little Book of Rust Macros

1 共 2 条评论, 1 页