我想编译以下代码:
struct Provider {} impl Provider { fn get_string<'a>(&'a self) -> &'a str { "this is a string" } } fn main() { let provider = Provider{}; let mut vec: Vec<&str> = Vec::new(); // PROBLEM: how do I say that this reference s here // needs to live as long as vec? let fun = |s: &str| { vec.push(s); }; fun(provider.get_string()); }
游乐场链接
这是我得到的编译错误:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/main.rs:9:22
|
9 | let mut vec: Vec<&str> = Vec::new();
| ^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the block at 11:24...
--> src/main.rs:11:25
|
11| let fun = |s: &str| {
| ^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:12:18
|
12| vec.push(s);
| ^
note: but, the lifetime must be valid for the block suffix following statement 2 at 13:6...
--> src/main.rs:13:7
|
13| };
| ^
note: ...so that variable is valid at time of its declaration
--> src/main.rs:11:9
|
11| let fun = |s: &str| {
| ^^^
Shepmaster.. 7
如果删除所有生命周期注释并让编译器推断完成其工作,您的代码就可以正常工作:
struct Provider; impl Provider { fn get_string(&self) -> &str { "this is a string" } } fn main() { let provider = Provider; let mut vec = Vec::new(); let mut fun = |s| { vec.push(s); }; fun(provider.get_string()); }
简而言之,没有办法明确地引用局部变量的生命周期,只有函数参数.但编译器知道如何做到这一点.
如果你真的需要它,你可以创建一个函数来允许注释生命周期:
fn thing<'a>(provider: &'a Provider) -> Vec<&'a str> { let mut vec: Vec<&'a str> = Vec::new(); { let mut fun = |s: &'a str| vec.push(s); fun(provider.get_string()); } // End mutable borrow of `vec` vec } fn main() { let provider = Provider; thing(&provider); }
为什么原始注释会阻止工作?
具体来说,就是这样:
let fun = |s: &str| { vec.push(s); };
这声明了关闭时的新生命周期.使用一个伪造的语法(你不能在闭包参数上声明生命周期),它将等同于:
let fun = <'a> |s: &'a str| { vec.push(s); };
这就是编译器出错的原因:
生命周期不能超过[封闭块]上定义的匿名生命#1
生成的生命周期与生成生命周期之间没有任何联系Provider
.将其遗漏允许编译器插入所需但不可用的生命周期.
如果删除所有生命周期注释并让编译器推断完成其工作,您的代码就可以正常工作:
struct Provider; impl Provider { fn get_string(&self) -> &str { "this is a string" } } fn main() { let provider = Provider; let mut vec = Vec::new(); let mut fun = |s| { vec.push(s); }; fun(provider.get_string()); }
简而言之,没有办法明确地引用局部变量的生命周期,只有函数参数.但编译器知道如何做到这一点.
如果你真的需要它,你可以创建一个函数来允许注释生命周期:
fn thing<'a>(provider: &'a Provider) -> Vec<&'a str> { let mut vec: Vec<&'a str> = Vec::new(); { let mut fun = |s: &'a str| vec.push(s); fun(provider.get_string()); } // End mutable borrow of `vec` vec } fn main() { let provider = Provider; thing(&provider); }
为什么原始注释会阻止工作?
具体来说,就是这样:
let fun = |s: &str| { vec.push(s); };
这声明了关闭时的新生命周期.使用一个伪造的语法(你不能在闭包参数上声明生命周期),它将等同于:
let fun = <'a> |s: &'a str| { vec.push(s); };
这就是编译器出错的原因:
生命周期不能超过[封闭块]上定义的匿名生命#1
生成的生命周期与生成生命周期之间没有任何联系Provider
.将其遗漏允许编译器插入所需但不可用的生命周期.