gpt4 book ai didi

rust - 为什么闭包的可变引用参数不会比函数调用更长久?

转载 作者:行者123 更新时间:2023-12-03 11:27:40 25 4
gpt4 key购买 nike

我正在使用 cssparser crate 来解析一些 CSS 代码。我想创建一个能够解析 type 函数的闭包。作为第一步,我创建了一个非常简单的代码:

use cssparser::{Parser, ParserInput};

fn main() {
let input_string = "type(\"image/png\")";
let mut parser_input = ParserInput::new(input_string);
let mut parser = Parser::new(&mut parser_input);

let parse_type = |p: &mut Parser| {
p.expect_function_matching("type")?;
Ok("OK")
};

let res = parse_type(&mut parser);
}

我收到以下错误:

error[E0282]: type annotations needed for the closure `fn(&mut Parser<'_, '_>) -> std::result::Result<&str, _>`
--> src/main.rs:9:43
|
9 | p.expect_function_matching("type")?;
| ^ cannot infer type of error for `?` operator
|
= note: `?` implicitly converts the error value into a type implementing `From<BasicParseError<'_>>`

如本文所述 answer ,我添加了闭包的返回类型:

    let parse_type = |p: &mut Parser| -> Result<&str, cssparser::BasicParseError> {
p.expect_function_matching("type")?;
Ok("OK")
};

我仍然有一个我不明白的错误:

error: lifetime may not live long enough
--> src/main.rs:9:9
|
8 | let parse_type = |p: &mut Parser| -> Result<&str, cssparser::BasicParseError> {
| - ---------------------------------------- return type of closure is std::result::Result<&str, BasicParseError<'2>>
| |
| has type `&mut Parser<'1, '_>`
9 | p.expect_function_matching("type")?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`

显然'1是在'2之前发布的。我的闭包的参数是引用怎么会这样呢?在调用我的关闭之后它应该仍然存在,对吗?

我尝试显式注释对象的生命周期,但无法找到正确的方法;我总是遇到“未声明的生命周期”错误。例如:

    let parse_type = |p: &mut Parser<'i, '_>| -> Result<&str, cssparser::BasicParseError<'i>> {
p.expect_function_matching("type")?;
Ok("OK")
};

最佳答案

不幸的是,closures can't declare lifetime arguments ,这将需要传达该函数的正确生命周期。将其移出到函数中会产生更好的错误:

use cssparser::{Parser, ParserInput};

fn parse_type(p: &mut Parser) -> Result<&str, cssparser::BasicParseError> {
p.expect_function_matching("type")?;
Ok("OK")
}

fn main() {
let input_string = "type(\"image/png\")";
let mut parser_input = ParserInput::new(input_string);
let mut parser = Parser::new(&mut parser_input);

let res = parse_type(&mut parser);
}
error[E0106]: missing lifetime specifier
--> src\main.rs:3:41
|
3 | fn parse_type(p: &mut Parser) -> Result<&str, cssparser::BasicParseError> {
| ----------- ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say which one of `p`'s 3 lifetimes it is borrowed from
help: consider introducing a named lifetime parameter
|
3 | fn parse_type<'a>(p: &'a mut Parser) -> Result<&'a str, cssparser::BasicParseError> {
| ^^^^ ^^^^^^^^^^^^^^ ^^^

error[E0106]: missing lifetime specifier
--> src\main.rs:3:58
|
3 | fn parse_type(p: &mut Parser) -> Result<&str, cssparser::BasicParseError> {
| ----------- ^^^^^^^^^^^^^^^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say which one of `p`'s 3 lifetimes it is borrowed from
help: consider introducing a named lifetime parameter
|
3 | fn parse_type<'a>(p: &'a mut Parser) -> Result<&str, cssparser::BasicParseError<'a>> {
| ^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^

编译器将尝试尽可能自动推断生命周期,但是p有三个生命周期&'1 Parser<'2, '3>涉及,所以它不知道什么生命周期&'_ strBasicParseError<'_>应该可以推导出来。

查看 Parser::expect_function_matching 的签名,您可能想要:

fn parse_type<'i>(p: &mut Parser<'i, '_>) -> Result<&'i str, cssparser::BasicParseError<'i>> {
p.expect_function_matching("type")?;
Ok("OK")
}

关于rust - 为什么闭包的可变引用参数不会比函数调用更长久?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66445015/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com