我继续尝试Rust,有一个问题。我想从std::io
有有用的消息,例如,当我试图打开文件时,我想在Err(err)
的情况下得到<file_name>
,但它不存在,例如:
fn read_to_string(file_name: &str) -> std::io::Result<String> {
let data = fs::read_to_string(file_name);
// let data = Ok(fs::read_to_string(file_name).expect(("Can not read file ".to_string() + file_name + "n").as_str()));
return data;
}
返回信息为:
[src/main.rs:26] res = Os {
code: 2,
kind: NotFound,
message: "No such file or directory",
}
没有任何<file_name>
-这是如此奇怪,我怀疑我做错了什么。<file_name>
是我最想要的数据
<file_name>
输出的正确(或惯用)方式是什么呢?注1:是的,有日志记录,但它并不总是可能的-假设您从某个点遍历file_system
,或者如果可能的话-您应该编写解析器以获得足够的信息。
注2:注释代码(与expect(...)
函数)-可以给我需要的信息,这是在这种情况下最令人不安的事情。
有一些关于可能为内置IO操作添加路径的讨论,但现在您可以只将错误映射为包含文件名的消息:
fn read_to_string(file_name: &str) -> std::io::Result<String> {
fs::read_to_string(file_name).map_err(|e| {
std::io::Error::new(
e.kind(),
format!("Error while reading file {}: {}", file_name, e),
)
})
}
如果您可以使用外部板条箱,anyhow
允许您将任意信息附加到任何错误,并保持完整的跟踪完整的错误堆栈:
use anyhow::{Context, Result};
use std::fs;
fn read_file (name: &str) -> Result<String> {
Ok (fs::read_to_string (name)
.with_context (|| format!("Could not read file {name}"))?)
}
fn main() -> Result<()> {
let contents = read_file ("unknown_file.txt")
.context ("Could not get file contents")?;
println!("File contents: {contents}");
Ok(())
}
游乐场
打印:
Error: Could not get file contents
Caused by:
0: Could not read file unknown_file.txt
1: No such file or directory (os error 2)