Rust异步封装同步代码实现Stream的生命周期问题解决
问题描述
我尝试基于搭载阻塞式capture方法的相机创建Stream,阻塞调用通过blocking::unblock进行包装,初始编写的代码如下:
use futures::stream; use rscam::{Camera, Config}; fn frame_stream() -> impl stream::Stream { let mut camera = Camera::new("/dev/video0").unwrap(); camera.start(&Config { interval: (1, 30), resolution: (1280, 720), format: b"H264", ..Default::default() }).unwrap(); stream::unfold(camera, |c| async move { let frame = blocking::unblock(|| c.capture().unwrap()).await; Some((frame, c)) }) }
编译时产生如下错误信息:
error[E0373]: closure may outlive the current function, but it borrows `c`, which is owned by the current function --> src/lib.rs:15:39 | 15 | let frame = blocking::unblock(|| c.capture().unwrap()).await; | ^^ - `c` is borrowed here | | | may outlive borrowed value `c` | note: function requires argument type to outlive `'static` --> src/lib.rs:15:21 | 15 | let frame = blocking::unblock(|| c.capture().unwrap()).await; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to force the closure to take ownership of `c` (and any other referenced variables), use the `move` keyword | 15 | let frame = blocking::unblock(move || c.capture().unwrap()).await; | ++++ error[E0505]: cannot move out of `c` because it is borrowed --> src/lib.rs:17:22 | 15 | let frame = blocking::unblock(|| c.capture().unwrap()).await; | ------------------------------------------ | | | | | | | borrow occurs due to use in closure | | borrow of `c` occurs here | argument requires that `c` is borrowed for `'static` 16 | 17 | Some((frame, c)) | ^ move out of `c` occurs here
我逻辑上认为闭包中捕获的c引用必然有效,因为返回c前会先await等待闭包执行完成,但不知道该如何向编译器证明该引用始终合法有效。
解决方案
报错的核心原因是blocking::unblock要求传入的闭包必须满足'static生命周期约束,不允许借用外部的非静态引用。只需要将相机实例c的所有权直接移动到阻塞任务的闭包内,在闭包中完成帧捕获操作后,同时返回捕获到的帧和相机实例c即可,修正后的代码如下:
stream::unfold(camera, |c| async move { Some( blocking::unblock(|| { (c.capture().unwrap(), c) }).await ) })
内容的提问来源于stack exchange,提问作者Stonks3141
相关产品推荐
相关产品推荐

