将成员函数体作为宏参数传递

Kyl*_*yes 7 rust

我试图将成员函数的主体作为宏参数传递。是否可以更改下面的代码以使其正常工作?

macro_rules! iterator{
    ($ty:ty, $ident:ident; $($state_ident:ident: $state_ty:ty), *; $next:block) => (
        struct $ident {                                         // ^ the parameter
            $($state_ident: $state_ty), *
        }

        impl Iterator for $ident {
            type Item = $ty;

            fn next(&mut self) -> Option<$ty> {
                $next // <- cannot refer to 'self' parameter in this block
            }
        }
    );
}

iterator!(i32, TestIterator; index: i32; {
    let value = Some(self.index);
    self.index += 1;
    value
});
Run Code Online (Sandbox Code Playgroud)

操场

编译器错误:

macro_rules! iterator{
    ($ty:ty, $ident:ident; $($state_ident:ident: $state_ty:ty), *; $next:block) => (
        struct $ident {                                         // ^ the parameter
            $($state_ident: $state_ty), *
        }

        impl Iterator for $ident {
            type Item = $ty;

            fn next(&mut self) -> Option<$ty> {
                $next // <- cannot refer to 'self' parameter in this block
            }
        }
    );
}

iterator!(i32, TestIterator; index: i32; {
    let value = Some(self.index);
    self.index += 1;
    value
});
Run Code Online (Sandbox Code Playgroud)

She*_*ter 8

一种解决方案是接受闭包而不是块:

macro_rules! iterator{
    ($ty:ty, $ident:ident; $($state_ident:ident: $state_ty:ty),*; $next:expr) => (
        struct $ident {
            $($state_ident: $state_ty), *
        }

        impl Iterator for $ident {
            type Item = $ty;

            fn next(&mut self) -> Option<$ty> {
                $next(self)
            }
        }
    );
}

iterator!(i32, TestIterator; index: i32; |me: &mut TestIterator| {
    let value = Some(me.index);
    me.index += 1;
    value
});

fn main() {}
Run Code Online (Sandbox Code Playgroud)

这需要显式传递self给闭包。self不能在闭包中使用标识符,因为self它只允许在函数的参数列表中声明。

您还需要指定闭包参数的类型,这是定义为变量并稍后使用的闭包的限制,而不是立即使用。