我是Rust新手,只看过Rust书籍,正在做一个需要捕获主显示屏幕截图的项目。我正在使用废板条箱。
fn screen_shot_and_save_image(iter:i32) {
let one_second = Duration::new(1, 0);
let one_frame = one_second / 60;
let mut buffer = None;
let display = Display::primary().expect("Couldn't find primary display.");
let mut capturer = Capturer::new(display).expect("Couldn't begin capture.");
let (mut w, mut h) = (capturer.width(), capturer.height());;
while buffer.is_none() {
// Wait until there's a frame.
match capturer.frame() {
Ok(buf) => {
buffer = Some(buf);
}
Err(error) => {
if error.kind() == WouldBlock {
// Keep spinning.
thread::sleep(one_frame);
continue;
} else {
panic!("Error: {}", error);
}
}
};
}
//work with buffer
}
capture .frame()的签名为
scrap::common::dxgi::Capturer
pub fn frame<'a>(&'a mut self) -> io::Result<Frame<'a>>
错误:
error[E0499]: cannot borrow `capturer` as mutable more than once at a time
--> srcmain.rs:103:15
|
103 | match capturer.frame() {
| ^^^^^^^^^^^^^^^^ `capturer` was mutably borrowed here in the previous iteration of the loop
基于类似的问题,我理解Rust不允许在循环中使用可变借用。但是,我需要在while循环中使用此函数,以防我得到会间歇返回空白图像的WouldBlock错误。我不能很好地理解编译器的错误或建议,所以任何帮助都会非常感激,谢谢!我将假设这是您的最小示例,因为我无法使您的示例运行:
use std::{thread, time::Duration};
struct Capturer {
data: String,
iteration: u32,
}
impl Capturer {
fn new() -> Self {
Self {
data: "Captured data!".to_string(),
iteration: 0,
}
}
fn frame(&mut self) -> Result<&str, Box<dyn std::error::Error>> {
self.iteration += 1;
if self.iteration == 3 {
Ok(&self.data)
} else {
Err(format!("Incorrect iteration: {}", self.iteration).into())
}
}
}
fn main() {
let mut buffer = None;
let mut capturer = Capturer::new();
while buffer.is_none() {
// Wait until there's a frame.
match capturer.frame() {
Ok(buf) => {
buffer = Some(buf);
}
Err(error) => {
println!("No result yet: {}", error);
thread::sleep(Duration::from_millis(100));
}
};
}
//work with buffer
println!("Received: '{}'", buffer.unwrap());
}
error[E0499]: cannot borrow `capturer` as mutable more than once at a time
--> src/main.rs:31:15
|
31 | match capturer.frame() {
| ^^^^^^^^^^^^^^^^ `capturer` was mutably borrowed here in the previous iteration of the loop
capturer.frame()
返回值包含生存期。这意味着返回值的某些部分引用了capturer
。并且由于.frame()
使用self
作为&mut self
,因此假定这是一个可变借用,并且每次只能有一个可变借用。
因为您将结果存储在循环之外,Rust不允许您再循环,因为下一次循环迭代可能再次调用.frame()
,尽管您仍然有一个可变引用。
use std::{thread, time::Duration};
struct Capturer {
data: String,
iteration: u32,
}
impl Capturer {
fn new() -> Self {
Self {
data: "Captured data!".to_string(),
iteration: 0,
}
}
fn frame(&mut self) -> Result<&str, Box<dyn std::error::Error>> {
self.iteration += 1;
if self.iteration == 3 {
Ok(&self.data)
} else {
Err(format!("Incorrect iteration: {}", self.iteration).into())
}
}
}
fn main() {
let mut capturer = Capturer::new();
let buffer = loop {
// Wait until there's a frame.
match capturer.frame() {
Ok(buf) => {
break buf;
}
Err(error) => {
println!("No result yet: {}", error);
thread::sleep(Duration::from_millis(100));
}
};
};
//work with buffer
println!("Received: '{}'", buffer);
}
No result yet: Incorrect iteration: 1
No result yet: Incorrect iteration: 2
Received: 'Captured data!'
我认为你可以让借用检查停止抱怨,如果你更明确地说明你的循环何时结束:
let buffer = loop {
// Wait until there's a frame.
match capturer.frame() {
Ok(buf) => {
break buf;
}
Err(error) => { ... }
};
}
如果这有效(我还没有测试过),这是因为它向借用检查器证明了capturer.frame()
的结果(存储在buffer
中)不会与对capturer.frame()
的另一个调用并发存在。编译器不是很聪明,不能看出buffer.is_none()
暗示buffer
没有存储capturer.frame()
。