即使满足 while 的条件,while let 也不会停止

While let does not stop even when the while's condition is fulfilled

我是 Rust 的新手,我正在尝试编写一个打开 websocket 10 秒的程序,从中接收数据然后停止。代码如下

let now = Instant::now();
while let n=now.elapsed().as_secs() < 10  {
    let msg = socket.read_message().expect("Error reading message");
    let msg = match msg {
        tungstenite::Message::Text(s) => { s }
        _ => { panic!() }
    };
    let parsed: serde_json::Value = serde_json::from_str(&msg).expect("Can't parse to JSON");
    let price_str=parsed["p"].as_str().unwrap();
    let price: f32 = price_str.parse().unwrap();
    

    write!(f,"1 \t").expect("unable to write");
    write!(f, "\t\t {} \n", price).expect("unable to write");
    println!("{}",n);
    
}

n 在 10 秒后变为假,但循环永远不会结束。我做错了什么?

感谢您的帮助。

while let n 将表达式 now.elapsed().as_secs() < 10 的结果绑定到 n。此绑定永远不会失败,因此您的循环永远不会退出。

编译器发出 lint 以防止此类错误:

warning: irrefutable `while let` pattern
  --> src/lib.rs:24:11
   |
24 |     while let n = now.elapsed().as_secs() < 10 {
   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(irrefutable_let_patterns)]` on by default
   = note: this pattern will always match, so the loop will never exit
   = help: consider instead using a `loop { ... }` with a `let` inside it

要修复您的代码段,您需要删除 let n 部分。或者以一种更不寻常且相当单一的方式,您可以通过 now.elapsed().as_secs() < 10 返回的值进行模式匹配:

while let true = now.elapsed().as_secs() < 10 {
    // do your thing
}

如果你想访问循环控制变量,你仍然可以通过以下方式将它绑定到一个变量:

let now = std::time::Instant::now();
while let n @ true = now.elapsed().as_secs() < 10 {
    println!("loop_control={}", n)
}

正如@Jmb 在评论中提到的,还有一个不是编译器错误的问题:循环体可能会无限期地阻塞,从而使超时无效。