rust - 为什么闭包的可变引用参数不会超过函数调用?
问题描述
我正在使用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<'_>>`
正如在这个答案中所读,我添加了我的闭包的返回类型:
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")
};
解决方案
不幸的是,闭包不能声明生命周期参数,这将需要传达此函数的正确生命周期。将其移出函数会产生更好的错误:
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>
,因此它不知道应该推导出&'_ str
什么生命周期。BasicParseError<'_>
查看 的签名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")
}
推荐阅读
- python - Python - 键盘模块 - 线程问题
- android - 如何从 kotlin 中的内部对象类访问类级别变量
- unix - 在 unix 中查找匹配的文本并替换下两行
- symfony - 如何在 symfony 中恢复页面的先前路由名称
- java - 在 Linux 托管服务器上安装 Eclipse 时出错 - JVM 终止退出代码 =2
- python - 相关性背后的直觉
- regex - 使用 vim 和 regex 翻译代码注释
- python - 当我将小部件添加到第二个窗口时,PyQt5 崩溃了 python
- node.js - 管道标准输入和标准输出之间的流
- r - 如何解释仿真模型中的 MAPE 值?