每次我认为我理解 Rust 的借用检查器时,我都会遇到这样的事情,这让我的大脑崩溃。
我正在使用包装 libpcap 的第三方库,其
Capture<Active>::next_packet()
调用将 &mut self
作为 arg 并返回 Packet
。如果在具有同步功能的循环中(sync_no_problem()
,见下文),我存储这个数据包,借用检查器工作正常。但是,如果我采用 完全相同的代码 并在异步函数中运行它(async_has_borrow_problem()
,如下),借用检查器会抱怨我无法重新借用与 &mut 相同的函数。具体错误:
error[E0499]: cannot borrow `cap` as mutable more than once at a time
--> src/main.rs:249:19
|
249 | let pkt = cap.next_packet().unwrap();
| ^^^^^^^^^^^^^^^^^ `cap` was mutably borrowed here in the previous iteration of the loop
250 | let owned_pkt = pkt.clone();
251 | captured.insert(1, owned_pkt);
| ----------------------------- first borrow used here, in later iteration of loop
如果我让一个异步函数(
nested_async_no_proble()
,如下)调用同步函数,真的很麻烦,借用检查器就可以了。有人可以向我解释这里发生了什么吗?
仅供参考:我试图简化示例以删除 pcap 引用,但我无法重现该问题,因此我认为这与它们的工作方式有关。我还在
.clone()
结构上尝试了丰富的 .to_owned()
和 Packet
认为可以解决问题,但事实并非如此。
use pcap::Capture;
fn sync_no_problem() {
let captured = std::collections::HashMap::new();
let cap = pcap::Device::lookup().unwrap().unwrap().open().unwrap();
for i in 0..5 {
let pkt = cap.next_packet().unwrap();
captured.insert(1, pkt);
}
println!("{:?}", captured);
}
async fn async_has_borrowing_problem() {
let mut captured = std::collections::HashMap::new();
let mut cap = pcap::Device::lookup().unwrap().unwrap().open().unwrap();
for i in 0..5 {
let pkt = cap.next_packet().unwrap();
let owned_pkt = pkt.clone();
captured.insert(1, owned_pkt);
}
println!("{:?}", captured);
}
async fn nested_async_no_problem() {
// this has no problems!!?
sync_no_problem();
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
sync_no_problem();
// calling this has problems
// async_has_borrowing_problem().await;
nested_async_no_problem().await;
}