gpt4 book ai didi

rust - Blanket impl、HRTB 和 "impl"抽象返回类型 : "expected bound lifetime parameter"

转载 作者:行者123 更新时间:2023-11-29 08:20:15 29 4
gpt4 key购买 nike

我开始了一个非常小的程序来玩 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

我既不明白为什么需要绑定(bind)生命周期参数,也不明白具体的生命周期是多少。

在我看来,返回的闭包有一些无法形容的类型。这种类型实现了 for <'a> Fn(&'a [u8]) -> Result<(&'a [u8], u8), ()> (并且编译器认识到这一点)。因此,它也应该由一揽子实现工具 Parser<u8, ()> ,或者我是这么想的。

最佳答案

The way I see it, the closure returned has some ineffable type. This type implements for <'a> Fn(&'a [u8]) -> Result<(&'a [u8], u8), ()> (and the compiler recognizes this).

仅当您指定它时。

考虑没有生命周期信息的函数签名:

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<...> 约束的生命周期,它会找到已经描述过的生命周期。

关于rust - Blanket impl、HRTB 和 "impl"抽象返回类型 : "expected bound lifetime parameter",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55340857/

29 4 0