传递模式作为函数参数?

问题描述 投票:1回答:2

我想知道有什么方法可以将一个模式作为函数参数来传递。

我有一个方法。

pub enum KEYWORD {
    assign(ASSIGN),
    symbol(SYMBOL),
    illegal
}

pub enum ASSIGN { /* some enums */ }
pub enum SYMBOL { /* some enums */ }

现在,我知道我可以用 match! 或我做的 expect! 宏,以配合我的键 l.key() 所以。

macro_rules! expect(($e:expr, $p:pat) => (
    match $e {
        $p => { true },
        _ => { false }
    }
));

expect!(l.key(), KEYWORD::symbol(_));

然而,我需要更多的情况下,我需要通过。KEYWORD::symbol(_) 作为函数参数,例如

impl l {
    pub fn expect_as_func(&self, KEYWORD) { /* some code */ }
}

l.expect_as_func(KEYWORD::symbol(_));

但是这个 l.expect_as_func(KEYWORD::symbol(_)); 是错误的,因为我使用的不是一个值,而是一个模式。

我试着用 proc_macroTokenStream:

pub fn expect(&mut self, patt: TokenStream) -> bool {
    match &self {
        patt => { true },
        _ => { false }
    }
}

但这也不行。

rust matching
2个回答
0
投票

从人机工程学的角度来看,你可以尝试实现以下函数 is_assign, is_symbol, is_illegal 在你的枚举上。

impl KEYWORD {
    fn is_assign(&self) -> bool {
        match self {
            KEYWORD::assign(_) => true,
            _ => false,
        }
    }
    // and so on
}

现在,由于这一切都变得乏味, 你可以创建一个宏来生成这些函数。

macro_rules! generate_is(($variant: pat, $fn_name: ident) => {
    fn $fn_name(&self) -> bool {
        match self {
            $variant => true,
            _ => false,
        }
    }
});

impl KEYWORD {
    generate_is!(KEYWORD::assign(_), is_assign);
    generate_is!(KEYWORD::symbol(_), is_symbol);
    generate_is!(KEYWORD::illegal, is_illegal);
}

这样,调用者只需说 keyword.is_assign() 或类似的)。

然后,在此基础上,你可以尝试发明一些能自动生成 is_...-从你的枚举中获取函数。(可能是通过一个程序化的宏)。


0
投票

我想说的是,从根本上说,模式不是应该作为函数参数传递到函数中的东西:而是应该传递一个具体的类型实例。

无论如何,如果这个任务的上下文真的需要它,你可以将整个函数实现为一个叫做 TokenSteam 内有图案,通过 proc_macro. 类似于以下内容:

let tokens = quote! {
    pub fn expect(&mut self) -> bool {
        match &self {
            #patt => { true },
            _ => { false }
       }
    }
};
© www.soinside.com 2019 - 2024. All rights reserved.