我已经阅读了 Rust 书和其他一些关于 lifetimes 的教程。我以为我将 lifetimes 理解为函数采用的通用参数,并且如何将其分配给函数的输入和输出参数会限制这些参数的 lifetime 。所以像 fn find<'a, 'b>(pattern: &'a str, text: &'b str) -> &'b str
意味着任何作为文本传入的东西都需要有一个 lifetime 至少与返回 value 一样长。但是在我正在编写的一个程序中,我遇到了一个错误,这让我认为我误解了关于 lifetimes 的一些基本内容。
我有一个带有签名的函数:
async fn check_git(requester: &mut Requester) -> Result<()>
Result
是 anyhow::Result
如果重要的话。
当我编译我得到错误:
error[E0726]: implicit elided lifetime not allowed here
--> src/scanner/git.rs:5:40
|
5 | pub async fn check_git(requester: &mut Requester) -> Result<()> {
| ^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>`
|
= note: assuming a `'static` lifetime...
我通过添加 lifetime 参数修复了编译器错误:async fn check_git<'a>(requester: &mut Requester<'a>) -> Result<()>
。我理解requester
不能有静态lifetime,因为我调用check_git
的方式,我传入的请求者的lifetime 是调用check_git
的函数的范围。但是我不完全理解我添加的 lifetime 注释的含义。
我对 lifetimes 的初学者理解是 fn check_git<'a>
只是指定 'a
是一个通用参数,然后当您将 'a
应用于多个参数时,它会限制这些参数的 lifetimes 之间的关系。但是当我只将 'a
应用于一个参数时, lifetime 注释没有添加约束或含义吗?
我要添加 lifetime 参数的 Requester
结构定义为:
struct Requester<'a> {
client: SendRequest<Body>,
resp: Option<Response<Body>>,
host: &'a str,
port: u16,
ctx: &'a SslContextRef,
}
回答1
但是当我只将 'a 应用于一个参数时,lifetime 注释中没有添加约束或含义?
正确的。这里的规则不是关于“你应该指定一个额外的约束”。相反,当您使用具有 lifetime 参数的类型时,您应该使其在语法上可见,其中涉及 lifetime 。对于引用,&
符号本身就足够了,但对于命名类型,您应该使 lifetime 本身可见。
(仍然允许在非 async
函数中使用隐藏的 lifetime 参数,但我建议使用 lint 配置 #![deny(rust_2018_idioms)]
禁止它们。)
这并不意味着您必须引入 'a
;您可以指定 '_
,这实际上意味着“请使用 lifetime 省略规则”,因此,通常但并非总是如此,“请在此处使用匿名的不同 lifetime”。所以,写:
pub async fn check_git(requester: &mut Requester<'_>) -> Result<()> {
这遵循与省略的 &
lifetimes 相同的规则,因此在这种情况下,它与编写无省略形式相同
pub async fn check_git<'a, 'b>(requester: &'a mut Requester<'b>) -> Result<()> {