问题描述
我的代码中存在关于终身推断的错误,并且我能够将代码简化为以下内容:
use std::collections::HashMap;
struct A<'a> {
x: &'a mut HashMap<&'a str,i32>,}
impl<'a> A<'a> {
fn new(x: &'a mut HashMap<&'a str,i32>) -> Self {
Self { x }
}
fn test(&mut self) {
let a = A::new(self.x);
}
}
fn main() {
}
由此导致的错误是
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
--> src/main.rs:13:17
|
13 | let a = A::new(self.x);
| ^^^^^^
|
note: first,the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 12:5...
--> src/main.rs:12:5
|
12 | / fn test(&mut self) {
13 | | let a = A::new(self.x);
14 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:13:24
|
13 | let a = A::new(self.x);
| ^^^^^^
note: but,the lifetime must be valid for the lifetime `'a` as defined on the impl at 7:6...
--> src/main.rs:7:6
|
7 | impl<'a> A<'a> {
| ^^
note: ...so that the expression is assignable
--> src/main.rs:13:24
|
13 | let a = A::new(self.x);
| ^^^^^^
= note: expected `&mut std::collections::HashMap<&str,i32>`
found `&mut std::collections::HashMap<&'a str,i32>`
我不了解这种情况下的错误是什么,但我确实发现,如果我将生命周期'b
添加到struct A
,使得{{ 1}}的生存期为str
,代码会编译。经过上述更改后,代码如下所示:
HashMap
但是,我不知道为什么这种改变有效。据我了解,两个生命周期都为'b
意味着A必须与use std::collections::HashMap;
struct A<'a,'b> {
x: &'a mut HashMap<&'b str,}
impl<'a,'b> A<'a,'b> {
fn new(x: &'a mut HashMap<&'b str,i32>) -> Self {
Self { x }
}
fn test(&mut self) {
let a = A::new(self.x);
}
}
fn main() {
}
一样长,并且'a
必须与所使用的HashMap
一样长。作为其键,我认为这没有问题。我也看不到更改如何为编译器添加任何其他信息。有人可以帮我澄清一下这种情况吗?
解决方法
将A::test()
函数更改为
fn test(&'a mut self) { // Add lifetime specification
let a = A::new(self.x);
}
它应该可以工作。
编译器表示无法推断A::new()
的生存期,并且第一个注释提到“匿名生存期”,这意味着编译器不知道self.x
中A::new(self.x)
的生存期。因此,我们只需要告诉编译器self
的生存期为'a
。