提前道歉,但这让我抓狂。每次我认为我理解了 Rust 的借用检查器时,我都会遇到这样的事情,这让我的大脑崩溃了:-(提前感谢你帮助我重新振作起来。
我正在使用包装 libpcap 的第三方库(https://github.com/rust-pcap/pcap),其 Capture::next_packet() [1] 调用将“&mut self”作为参数,并且返回一个“数据包”。如果在具有同步功能的循环中(
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 引用,但我无法重现该问题,因此我认为这与它们的工作方式有关。我还在 Packet 结构上尝试了丰富的 .clone() 和 .to_owned() 认为可以解决问题但它没有:-(
提前谢谢你。
[1] 捕获::下一个数据包():https://github.com/rust-pcap/pcap/blob/main/src/lib.rs#L1238 [2] 数据包:https://github.com/rust-pcap/pcap/blob/main/src/lib.rs#L654
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;
}