我在Rust中启动了一个很小的程序来与解析器组合器一起玩,很快遇到一个错误,发现奇怪:
trait Parser<T, E> {
fn parse<'a>(&self, input: &'a [u8]) -> Result<(&'a [u8], T), E>;
}
impl<F, T, E> Parser<T, E> for F
where
F: for<'a> Fn(&'a [u8]) -> Result<(&'a [u8], T), E>,
{
fn parse<'a>(&self, input: &'a [u8]) -> Result<(&'a [u8], T), E> {
(*self)(input)
}
}
// why can't I write:
// fn byte(b: u8) -> impl Parser<u8, ()> {
// this works, and the blanket Parser impl picks it up correctly
fn byte(b: u8) -> impl for<'a> Fn(&'a [u8]) -> Result<(&'a [u8], u8), ()> {
move |input: &[u8]| match input.first() {
Some(x) if *x == b => Ok((&input[1..], *x)),
_ => Err(()),
}
}
fn main() {
println!("{:?}", byte(b'c').parse(b"c123"));
}
byte
的注释掉的签名(返回impl Parser<u8, ()>
)无法编译为:
error[E0271]: type mismatch resolving `for<'a> <[closure@parser.rs:14:5: 19:6 b:_] as std::ops::FnOnce<(&'a [u8],)>>::Output == std::result::Result<(&'a [u8], u8), ()>`
--> parser.rs:12:19
|
12 | fn byte(b: u8) -> impl Parser<u8, ()> {
| ^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'a, found concrete lifetime
|
= note: required because of the requirements on the impl of `Parser<u8, ()>` for `[closure@parser.rs:14:5: 19:6 b:_]`
= note: the return type of a function must have a statically known size
我既不理解为什么期望绑定寿命参数,也没有找到具体的寿命。
我的看法是,返回的闭包具有某种无法定义的类型。此类型实现for <'a> Fn(&'a [u8]) -> Result<(&'a [u8], u8), ()>
(并且编译器可以识别)。结果,它也应该由隐式实现Parser<u8, ()>
来实现,或者我以为如此。
答案 0 :(得分:0)
我的看法是,返回的闭包具有某种无法定义的类型。这种类型实现了<'a> Fn(&'a [u8])-> Result <(&'a [u8],u8),()>(并且编译器可以识别出来)。
只有在您指定它的情况下。
考虑没有生命周期信息的功能签名:
fn byte(b: u8) -> impl Fn(&[u8]) -> Result<(&[u8], u8), ()>
如果您写下被淘汰的寿命,则给出
fn byte<'a>(b: u8) -> impl Fn(&'a [u8]) -> Result<(&'a [u8], u8), ()>
这不会实现高阶for<'a> Fn ...
-它仅对某个固定的Fn
实现'a
特性,该特性由调用者确定为byte
。
这是编译器所抱怨的具体生存期-期望找到for<...>
约束的生存期,而是找到已经描述的生存期。