写!宏在 Rust 中无法与异步函数一起正常工作

write! macro does not work properly with async function in Rust

提问人:jianliang wang 提问时间:10/14/2023 更新时间:10/14/2023 访问量:62

问:

这是我的功能的简化版本:

async fn show_status(root_dir: &PathBuf, mut output: impl std::io::Write) -> Result<(), Error> {
    writeln!(output, "status:");

    let mut commponent_ids = walk_components(&StatusVisitor::new(), &root_dir, None).await?;
    writeln!(output, "ids: {:?}", commponent_ids);
    output.flush();

    Ok(())
}

这是我的测试用例:

#[cfg(test)]
mod tests {
    use super::show_status;

    #[tokio::test]
    async fn test_show_status() {
        let mut output = Vec::new();
        show_status(&main_repo_dir, &mut output).await;

        assert_eq!(std::str::from_utf8(output.as_slice()).unwrap(), "status:\nids: [0, 1]");
    }
}

我认为案件可能会按预期通过,但事实是我遇到了以下失败:

assertion `left == right` failed
  left: "status:\n"
 right: "status:\nids: [0, 1]\n"

我不知道为什么在输出中看不到第二行。谁能给我一些帮助?

我问过 chatgpt,它告诉我使用这些特征而不是 .但是当我尝试解决方案时,没有任何改变。tokio::io::AsyncWriteExtstd::io::Write

我还尝试过直接在主函数中调用函数,而不是在测试用例中调用它。出乎意料的是,我工作正常。我在 stdout 中看到了两行。

所以我的问题是:测试用例发生了什么?为什么我在异步测试用例的输出中看不到第二行?

rust async-await io rust-tokio

评论

1赞 isaactfa 10/14/2023
看起来像错误,函数在第二个之前提前返回,也许吧?您应该检查返回的内容。这应该与.walk_componentswriteln!show_statusasync
0赞 jianliang wang 10/14/2023
我又问了chatgpt,得到了新的答案。我似乎解释了我的问题是什么:从您提供的代码来看,该函数似乎是一个异步函数,并且您没有在测试用例中正确等待它。这可能是您遇到的问题的原因。在 Rust 中,调用异步函数时,需要使用关键字等待函数完成。如果不使用 ,该函数将立即返回 future 并返回,并且不会执行实际计算。show_status.await.await
2赞 jthulhu 10/14/2023
@jianliangwang chatgpt 的答案是关于您的问题(或至少就您发布的代码而言)的胡说八道。
1赞 cafce25 10/14/2023
请创建一个最小的可重现示例,指出问题可能是错误,但您没有显示它的实现。walk_components
0赞 jianliang wang 10/14/2023
@jthulhu我采纳了 chatgpt 的建议,测试用例惊人地通过了。正如chatgpt所说,我把下面一行改成了这样: 从结果来看,他说的似乎是有道理的。show_status(&main_repo_dir, &mut output).await; show_status(&main_repo_dir, &mut output).await.unwrap();

答: 暂无答案