我是Rust的新手,我正在尝试在其中创建组合子解析器。下面是代码:
enum Parser<T: Copy + Eq> {
Ok,
Eof,
Satisfy { predicate: Box<dyn Fn(&T) -> bool> },
Element { elem : T }
}
impl<T: Copy + Eq> Parser<T> {
fn parse<'a, P>(&self, input: &'a [T]) -> Option<(&'a [T], P)>
where
P: Default,
T: Into<P>
{
match self {
Parser::Ok => Some((input, P::default())),
Parser::Eof => match input {
[] => None,
_ => Some((input, P::default())),
},
Parser::Satisfy { predicate } => match input {
[] => None,
[x, rest @ ..] => {
if predicate(x) {
Some((rest, T::into(*x)))
} else {
None
}
}
},
Parser::Element { elem } => {
let to_match = *elem;
Parser::Satisfy { predicate: Box::new(move|x| *x == to_match) }.parse(input)
}
}
}
}
Parser::Ok、Parser::Eof和Parser::Satisfy工作正常,但我在实现Parser::Element(必须仅精确到元素)时遇到了困难。我想通过创建Parser::Satisfy实现方法解析,并在参数x和给定elem之间使用eq predicate 。但我遇到了此错误:
error[E0310]: the parameter type `T` may not live long enough
--> src/lib.rs:32:46
|
32 | Parser::Satisfy { predicate: Box::new(move|x| *x == to_match) }.parse(input)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
8 | impl<T: Copy + Eq + 'static> Parser<T> {
| +++++++++
我觉得生命存在一些问题,但我不知道如何解决它。
1条答案
按热度按时间biswetbf1#
dyn Trait
包含一些东西,这些东西可能有生存期,因此dyn Trait
也有生存期。这个生存期和函数的生存期一样,可以省略。完整的规则有些复杂,但是在ADT中,生存期被假定为
'static
。您可以使用dyn Trait + 'lifetime
指定另一个生存期。因此,枚举中的
Box<dyn Fn(&T) -> bool>
实际上是Box<dyn Fn(&T) -> bool + 'static>
。但是问题是你分配给它的函数捕获
to_match
,类型为T
,并且类型T
可能包含非'static
的生存期,例如,它可能包含&'non_static str
,这就是错误。这有两种可能的解决方案。
要么接受这一点,并要求
T
为'static
:或者允许函数的生存期为非
'static
: