获取 move closure 的引用报错,请指正问题所在
有下面的代码
1. fn boxed_closure(closures: &mut Vec<&dyn Fn()>) {
2. let v = "abc".to_string();
3. let v = 1;
4. closures.push(&||println!("first"));
5. closures.push(&|| println!("second"));
6. closures.push(&move || println!("v's value:{}",v));
7. }
8.
9. fn main() {
10. let mut closures:Vec<&dyn Fn()> = vec![];
11.
12. boxed_closure(&mut closures);
13. }
在函数 boxed_closure 中,第 4 行和第 5 行都没有报错,但是第6行报错:
1 | fn boxed_closure(closures: &mut Vec<&dyn Fn()>) {
| - let's call the lifetime of this reference `'1`
...
6 | closures.push(&move || println!("v's value:{}",v));
| ---------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- temporary value is freed at the end of this statement
| | |
| | creates a temporary value which is freed while still in use
| argument requires that borrow lasts for `'1`
看了rust 的 temporary lifetime extentsion 的相关文档没有找到问题的原因,因为文档中就没有提到 move closure 相关的临时对象。
我猜测报错的原因是,move closure 虽然把 v 的所有权转移到 closure 中,但是rust仍然认为 closure 使用的是函数 boxed_closure 中局部变量 v 的 &v,所以导致编译失败。
请哪位大牛解答一下,谢谢!
报错说明的是你持有了一个临时值的引用。
closures.push(&move || println!("v's value:{}",v));
中你创建一个临时的闭包,然后把这个闭包的引用存入Vec
中,但是语句这个闭包在语句结束后就会被释放,导致Vec
中存入的引用指向一个无效的内存。@长日将尽 这位大佬其实已经告诉你为什么了,可以参考我的刚刚记录的一个笔记。 @dewei
www.yuque.com/anruofusheng/bytlpr/...
这里传递过去的还是临时值,rust是不允许这种操作的,你这个还是想着引用传递的那一套,除非你搞一些骚操作。你要么clone一下,要么就使用指针。
没有不认真看你的代码,已经说的很清楚了。move只是修改所有权,又不是提升生命周期的。
给你完整可以运行的代码吧,你可以自己查一个Box是干什么的@dewei
对计算机内存管理、堆栈管理没有什么概念的话,建议还是听编译器的提示修改。楼主让我想起来之前给某些大公司做技术支持时,有个老哥使用定时器判断http请求是否超时,然后还觉得自己搞的很对,不理解这样为什么不行。把我怼了半天。