如何使用结构和实现的生命周期为实现推断适当的生命周期?
How to infer an appropriate lifetime for an implementation using lifetimes for structs and impl?
如何解决此错误?当我在 impl
中使用 "anonymous lifetime" 时,我到底在告诉编译器什么?
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
});
}
当我尝试编译时,出现以下错误:
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<'_>
我如何解决这个错误,当我在 impl Game
上指定一个生命周期时,我到底在告诉编译器什么,而我已经在结构上有一个生命周期?
How do I resolve this error?
从函数中删除通用生命周期,在 impl
块中提供生命周期名称而不是使用匿名生命周期,然后在函数参数中使用命名生命周期。从 &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,
});
}
}
另请参阅:
What exactly am I doing when I use the "anonymous lifetime" in impl?
您实际上是在陈述 "I know there's a lifetime here, but I don't care about it"。但是,您的情况并非如此。您确实关心参数化类型的生命周期,因为这是您的变量需要匹配的。
另请参阅:
for a struct with a function pointer in it
这与函数指针无关。当编程遇到问题时,我建议创建一个 minimal, reproducible example,去掉不会使错误消失的东西。这使您可以专注于手头的问题。例如,这会重现相同的错误:
struct Game<'a> {
handlers: Vec<&'a str>,
}
impl Game<'_> {
fn match_str<'a>(&mut self, label: &'a str) {
self.handlers.push(label);
}
}
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?
我怀疑您的困惑源于对 Rust 中声明和使用生命周期的方式的不完全理解。
结构生命周期
为了在结构上使用生命周期,您声明生命周期在 <>
中与您声明的结构名称相邻,然后 refer 指向结构定义中的生命周期。重要的是,请注意声明的生命周期仅限于结构定义 - 它在外部没有任何意义。
例如(使用@Shepmaster 提供的 MRE):
struct Game<'a> {
handlers: Vec<&'a str>,
}
结构 Game
包含一个字符串引用向量,被引用的字符串必须至少与 Game
结构一样长。
实现生命周期
在 impl 块上使用生命周期说明符时,您 声明 在与 impl 关键字相邻的 <>
内的生命周期,之后您可以 引用在正在实现的结构和实现本身内部的生命周期,像这样:
impl<'b> Game<'b> {
fn match_str(&mut self, label: &'b str) {
self.handlers.push(label);
}
}
请注意,我在这里使用了一个完全不同的生命周期名称 ('b
) 来说明结构上的生命周期声明独立于 impl 块上的生命周期声明。
分解:
impl<'b>
这意味着我们正在为结构定义一个实现,并且在该定义中我们将使用生命周期 'b
Game<'b> {
这意味着 impl 是针对生命周期为 'b
的结构体 Game
- 因此在此实现中对 self
的任何引用都将自动具有生命周期 'b
还有。
fn match_str(&mut self, label: &'b str) {
这里我们定义了方法match_str
,它接受一个参数label
。 label
是一个字符串切片,它也具有生命周期 'b
- 因此它必须至少持续到调用该方法的 self
时长。
在你的原始代码中,你有这样的东西:
impl Game<'_> {
fn match_str<'a>(&mut self, label: &'a str) {
...
}
}
这是在告诉编译器:
- 您正在启动一个新的 impl 块,并且没有在 impl 级别声明生命周期
- 该实现是针对结构
Game
;这个结构有一个生命周期参数,但我们不关心它,我们不会将它绑定到实现的任何元素
- 我们正在定义一个方法
match_str
,我们正在声明一个生命周期'a
,我们可以在函数签名的其余部分 中引用它
- 我们有一个参数
label
,其生命周期为 a
,但我们并未将此生命周期与任何其他事物相关联
更多信息:
如何解决此错误?当我在 impl
中使用 "anonymous lifetime" 时,我到底在告诉编译器什么?
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
});
}
当我尝试编译时,出现以下错误:
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<'_>
我如何解决这个错误,当我在 impl Game
上指定一个生命周期时,我到底在告诉编译器什么,而我已经在结构上有一个生命周期?
How do I resolve this error?
从函数中删除通用生命周期,在 impl
块中提供生命周期名称而不是使用匿名生命周期,然后在函数参数中使用命名生命周期。从 &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,
});
}
}
另请参阅:
What exactly am I doing when I use the "anonymous lifetime" in impl?
您实际上是在陈述 "I know there's a lifetime here, but I don't care about it"。但是,您的情况并非如此。您确实关心参数化类型的生命周期,因为这是您的变量需要匹配的。
另请参阅:
for a struct with a function pointer in it
这与函数指针无关。当编程遇到问题时,我建议创建一个 minimal, reproducible example,去掉不会使错误消失的东西。这使您可以专注于手头的问题。例如,这会重现相同的错误:
struct Game<'a> {
handlers: Vec<&'a str>,
}
impl Game<'_> {
fn match_str<'a>(&mut self, label: &'a str) {
self.handlers.push(label);
}
}
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?
我怀疑您的困惑源于对 Rust 中声明和使用生命周期的方式的不完全理解。
结构生命周期
为了在结构上使用生命周期,您声明生命周期在 <>
中与您声明的结构名称相邻,然后 refer 指向结构定义中的生命周期。重要的是,请注意声明的生命周期仅限于结构定义 - 它在外部没有任何意义。
例如(使用@Shepmaster 提供的 MRE):
struct Game<'a> {
handlers: Vec<&'a str>,
}
结构 Game
包含一个字符串引用向量,被引用的字符串必须至少与 Game
结构一样长。
实现生命周期
在 impl 块上使用生命周期说明符时,您 声明 在与 impl 关键字相邻的 <>
内的生命周期,之后您可以 引用在正在实现的结构和实现本身内部的生命周期,像这样:
impl<'b> Game<'b> {
fn match_str(&mut self, label: &'b str) {
self.handlers.push(label);
}
}
请注意,我在这里使用了一个完全不同的生命周期名称 ('b
) 来说明结构上的生命周期声明独立于 impl 块上的生命周期声明。
分解:
impl<'b>
这意味着我们正在为结构定义一个实现,并且在该定义中我们将使用生命周期 'b
Game<'b> {
这意味着 impl 是针对生命周期为 'b
的结构体 Game
- 因此在此实现中对 self
的任何引用都将自动具有生命周期 'b
还有。
fn match_str(&mut self, label: &'b str) {
这里我们定义了方法match_str
,它接受一个参数label
。 label
是一个字符串切片,它也具有生命周期 'b
- 因此它必须至少持续到调用该方法的 self
时长。
在你的原始代码中,你有这样的东西:
impl Game<'_> {
fn match_str<'a>(&mut self, label: &'a str) {
...
}
}
这是在告诉编译器:
- 您正在启动一个新的 impl 块,并且没有在 impl 级别声明生命周期
- 该实现是针对结构
Game
;这个结构有一个生命周期参数,但我们不关心它,我们不会将它绑定到实现的任何元素 - 我们正在定义一个方法
match_str
,我们正在声明一个生命周期'a
,我们可以在函数签名的其余部分 中引用它
- 我们有一个参数
label
,其生命周期为a
,但我们并未将此生命周期与任何其他事物相关联
更多信息: