[英]How to infer an appropriate lifetime for an implementation using lifetimes for structs and impl?
How do I resolve this error?如何解决此错误? What exactly am I telling the compiler when I use the "anonymous lifetime" in impl
?当我在impl
中使用“匿名生命周期”时,我到底在告诉编译器什么?
struct LineHandlerInfo<'a> {
label: &'a str,
match_literal: &'a str,
f: fn(&str) -> Option<&str>,
}
struct Game<'a> {
handlers: Vec<LineHandlerInfo<'a>>,
}
impl Game<'_> {
fn match_str<'a>(
&'a mut self,
label: &'a str,
match_literal: &'a str,
mut f: fn(&str) -> Option<&str>,
) {
let mut lh = LineHandlerInfo {
label,
match_literal,
f,
};
self.handlers.push(lh);
}
}
fn main() {
let mut g = Game {
handlers: Vec::new(),
};
g.match_str("echo hello", "hello", |s| {
println!("{}", s);
None
});
}
When I attempt to compile, I get the following error:当我尝试编译时,出现以下错误:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
--> src/main.rs:18:22
|
18 | let mut lh = LineHandlerInfo {
| ^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the method body at 12:18...
--> src/main.rs:12:18
|
12 | fn match_str<'a>(
| ^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:19:13
|
19 | label,
| ^^^^^
note: but, the lifetime must be valid for the lifetime '_ as defined on the impl at 11:11...
--> src/main.rs:11:11
|
11 | impl Game<'_> {
| ^^
= note: ...so that the expression is assignable:
expected LineHandlerInfo<'_>
found LineHandlerInfo<'_>
How do I resolve this error and what exactly am I telling the compiler when I specify a lifetime on impl Game
when I already have a lifetime on the struct?我该如何解决这个错误,当我在impl Game
上指定一个生命周期时,当我在结构上已经有一个生命周期时,我到底告诉编译器什么?
How do I resolve this error and what exactly am I telling the compiler when I specify a lifetime on impl Game when I already have a lifetime on the struct?我该如何解决这个错误,当我在 impl Game 上指定一个生命周期时,当我在结构上已经有一个生命周期时,我到底告诉编译器什么?
I suspect your confusion stems from an incomplete understanding of the way in which lifetimes are declared and used in Rust.我怀疑您的困惑源于对 Rust 中声明和使用生命周期的方式的不完全理解。
In order to use a lifetime on a struct, you declare the lifetime inside the <>
adjacent to the name of the struct you are declaring, and then refer to that lifetime inside the struct definition.为了在结构上使用生命周期,您在<>
中声明与您正在声明的结构名称相邻的生命周期,然后在结构定义中引用该生命周期。 Importantly, note that the lifetime declared there is scoped to the struct definition - it has no meaning outside.重要的是,请注意,在那里声明的生命周期仅限于结构定义 - 它在外部没有任何意义。
For example (using the MRE that @Shepmaster provided):例如(使用@Shepmaster 提供的 MRE):
struct Game<'a> {
handlers: Vec<&'a str>,
}
The struct Game
contains a vector of references to strings, and the strings which are referenced must last at least as long as the Game
struct.结构体Game
包含一个对字符串的引用向量,并且被引用的字符串必须至少与Game
结构体一样长。
When using a lifetime specifier on an impl block, you declare the lifetime inside the <>
adjacent to the impl keyword, after which you may refer to the lifetime both in the struct being implemented, and inside the implementation itself, like this:在 impl 块上使用生命周期说明符时,您在 impl 关键字旁边的<>
内声明生命周期,之后您可以在正在实现的结构和实现本身中引用生命周期,如下所示:
impl<'b> Game<'b> {
fn match_str(&mut self, label: &'b str) {
self.handlers.push(label);
}
}
Note that I am using an entirely different lifetime name here ( 'b
) to illustrate that the the lifetime declaration on the struct is independent of the one on the impl block.请注意,我在这里使用了一个完全不同的生命周期名称( 'b
)来说明结构上的生命周期声明独立于 impl 块上的声明。
Breaking this down:打破这个:
impl<'b>
This means that we are defining an implementation for a struct, and within that definition we will use the lifetime 'b
这意味着我们正在为结构定义一个实现,并且在该定义中我们将使用生命周期'b
Game<'b> {
This means that the impl is for the struct Game
with lifetime 'b
- so any references to self
inside this implementation are going to automatically have lifetime 'b
as well.这意味着 impl 用于具有生命周期'b
的结构Game
- 因此在此实现中对self
的任何引用也将自动具有生命周期'b
。
fn match_str(&mut self, label: &'b str) {
Here we define the method match_str
which takes an argument label
.这里我们定义了label
match_str
label
is a string slice which also has the lifetime 'b
- so it must last at least as long as the self
that the method is called on. label
是一个字符串切片,它也有生命周期'b
- 所以它必须至少与调用该方法的self
一样长。
In your original code, you had something like this:在您的原始代码中,您有以下内容:
impl Game<'_> {
fn match_str<'a>(&mut self, label: &'a str) {
...
}
}
This was telling the compiler:这告诉编译器:
Game
;该实现是针对 struct Game
的; this struct has a lifetime parameter but we don't care about it and we are not going to tie it to any element of the implementation这个结构有一个生命周期参数,但我们不关心它,我们不会将它绑定到实现的任何元素match_str
, and we are declaring a lifetime 'a
which we can refer to in the rest of the function signature我们正在定义一个方法match_str
,并且我们正在声明一个生命周期'a
,我们可以在 function 签名的 rest 中引用它label
which has the lifetime a
, but we aren't relating this lifetime to anything else我们有一个参数label
的生命周期a
,但我们没有将此生命周期与其他任何东西联系起来More information:更多信息:
How do I resolve this error?如何解决此错误?
Remove the generic lifetime from the function, provide a name for the lifetime on the impl
block instead of using the anonymous lifetime, then use the named lifetime in the function arguments.从 function 中删除通用生命周期,在impl
块上为生命周期提供名称而不是使用匿名生命周期,然后在 function arguments 中使用命名生命周期。 Remove the lifetime from &self
:从&self
中删除生命周期:
impl<'a> Game<'a> {
fn match_str(&mut self, label: &'a str, match_literal: &'a str, f: fn(&str) -> Option<&str>) {
self.handlers.push(LineHandlerInfo {
label,
match_literal,
f,
});
}
}
See also:也可以看看:
What exactly am I doing when I use the "anonymous lifetime" in impl?当我在 impl 中使用“匿名生命周期”时,我到底在做什么?
You are effectively stating "I know there's a lifetime here, but I don't care about it".您实际上是在说“我知道这里有一生,但我不在乎”。 However, that's not true for your case;但是,您的情况并非如此。 you do care about the lifetime that parameterizes the type because that's what your variables need to match.您确实关心参数化类型的生命周期,因为这是您的变量需要匹配的。
See also:也可以看看:
'_
, the anonymous lifetime in the Edition Guide '_
,版本指南中的匿名生命周期for a struct with a function pointer in it对于其中带有 function 指针的结构
This has nothing to do with function pointers.这与 function 指针无关。 When encountering problems while programing, I recommend creating a minimal, reproducible example , stripping out things that don't make the error go away.在编程时遇到问题时,我建议创建一个最小的、可重现的示例,去掉不会导致错误 go 消失的东西。 This allows you to focus on exactly the problem at hand.这使您可以准确地专注于手头的问题。 For example, this reproduces the same error:例如,这会重现相同的错误:
struct Game<'a> {
handlers: Vec<&'a str>,
}
impl Game<'_> {
fn match_str<'a>(&mut self, label: &'a str) {
self.handlers.push(label);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.