【发布时间】:2020-03-28 18:59:02
【问题描述】:
我最近遇到了 Rust 的高级特征边界,并认为我可以使用它们来使我正在编写的解析器中的一些函数更通用。但是,我所做的修改给了我一条我无法正面或反面的错误消息。
这就是我现在所拥有的有效方法:
use nom::bytes::complete::is_not;
use nom::character::complete::multispace0;
use nom::combinator::verify;
use nom::error::{
ParseError,
VerboseError,
};
use nom::sequence::terminated;
use nom::IResult;
fn one_token<'a, E>(input: &'a str) -> IResult<&str, &str, E>
where
E: ParseError<&'a str>,
{
terminated(is_not(" \t\r\n"), multispace0)(input)
}
fn str_token<'a, E>(expected_string: String) -> impl Fn(&'a str) -> IResult<&str, &str, E>
where
E: ParseError<&'a str>,
{
verify(one_token, move |actual_string| {
actual_string == expected_string
})
}
这样编译。但是,我的直觉告诉我,我从str_token 返回的impl Fn 受str_token 上的生命周期参数约束并不一定很好。我相信这样可能会不必要地限制返回的 impl Fn 特征的有用性。所以我想我可以修改它以返回一个适用于任何生命周期 'b 的 impl Fn,而不管工厂函数 str_token_hrtb 的生命周期是什么:
fn str_token_hrtb<'a, E>(
expected_string: String,
) -> impl for<'b> Fn(&'b str) -> IResult<&str, &str, E>
where
E: ParseError<&'a str>,
{
verify(one_token, move |actual_string| {
actual_string == expected_string
})
}
现在,编译器给了我这些错误:
error[E0277]: expected a `std::ops::Fn<(&'b str,)>` closure, found `impl std::ops::Fn<(&str,)>`
--> src/main.rs:29:6
|
29 | ) -> impl for<'b> Fn(&'b str) -> IResult<&str, &str, E>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `Fn<(&'b str,)>` closure, found `impl std::ops::Fn<(&str,)>`
|
= help: the trait `for<'b> std::ops::Fn<(&'b str,)>` is not implemented for `impl std::ops::Fn<(&str,)>`
= note: the return type of a function must have a statically known size
error[E0271]: type mismatch resolving `for<'b> <impl std::ops::Fn<(&str,)> as std::ops::FnOnce<(&'b str,)>>::Output == std::result::Result<(&'b str, &'b str), nom::internal::Err<E>>`
--> src/main.rs:29:6
|
29 | ) -> impl for<'b> Fn(&'b str) -> IResult<&str, &str, E>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'b, found concrete lifetime
|
= note: the return type of a function must have a statically known size
我不明白如何阅读。是不是说for<'b> std::ops::... 的返回值没有实现特征verify?如果是这样,为什么不呢?为什么str_token 不存在同样的问题?另外,我找不到任何方法来解释第二条type mismatch 错误消息。
谁能提供一些关于我在这里做错了什么以及编译器试图告诉我什么的见解?
更新:
我正在使用此处的 nom 解析库:https://github.com/Geal/nom/
另外,verify 函数的代码在这里:https://github.com/Geal/nom/blob/851706460a9311f7bbae8e9b7ee497c7188df0a3/src/combinator/mod.rs#L459
另一个更新:
因为我意识到我可能没有提出足够具体的问题,所以决定关闭它。
【问题讨论】:
标签: rust