获取 move closure 的引用报错,请指正问题所在 | rust | rust 技术论坛-江南app体育官方入口

有下面的代码

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,所以导致编译失败。

请哪位大牛解答一下,谢谢!

讨论数量: 9

报错说明的是你持有了一个临时值的引用。closures.push(&move || println!("v's value:{}",v)); 中你创建一个临时的闭包,然后把这个闭包的引用存入 vec 中,但是语句这个闭包在语句结束后就会被释放,导致 vec 中存入的引用指向一个无效的内存。

8个月前
(楼主) 8个月前
(作者) 8个月前

@长日将尽 这位大佬其实已经告诉你为什么了,可以参考我的刚刚记录的一个笔记。 @dewei

这里传递过去的还是临时值,rust是不允许这种操作的,你这个还是想着引用传递的那一套,除非你搞一些骚操作。你要么clone一下,要么就使用指针。

8个月前
8个月前
(楼主) 8个月前
fn boxed_closure(closures: &mut vec<box<dyn fn()>>) {
    let v = 1;
    closures.push(box::new(move || println!("first")));
    closures.push(box::new(move || println!("second")));
    let f = box::new(move || println!("v's value:{}", v));
    closures.push(f);
}
fn main() {
    let mut closures: vec<box<dyn fn()>> = vec![];
    boxed_closure(&mut closures);
}

没有不认真看你的代码,已经说的很清楚了。move只是修改所有权,又不是提升生命周期的。

给你完整可以运行的代码吧,你可以自己查一个box是干什么的@dewei

8个月前
(楼主) 7个月前

对计算机内存管理、堆栈管理没有什么概念的话,建议还是听编译器的提示修改。楼主让我想起来之前给某些大公司做江南app体育官方入口的技术支持时,有个老哥使用定时器判断http请求是否超时,然后还觉得自己搞的很对,不理解这样为什么不行。把我怼了半天。

7个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
网站地图