Rust中如何让unwrap()调用display()而非debug()输出错误?
问题
我在Rust程序里定义了返回Result<String, String>的函数:fn foo() -> Result<String, String>,返回的错误字符串格式是lorem\nipsum这种带转义换行的。调用foo.unwrap()后,错误输出是lorem\nipsum,但我想要它正常换行显示成:
lorem ipsum
查了下原因是unwrap()调用的是Debug trait的实现,而String的Debug会把转义字符原样输出,Display才会解析换行。有没有简便方法让unwrap()用Display来显示错误?
解决方案
unwrap()的错误输出逻辑是硬编码调用Debug的,没法直接让它改用Display,不过有几个简便的替代方案:
手动处理错误,用Display输出
放弃直接用unwrap(),改用match或if let处理Result,拿到错误后用eprintln!("{}", err)输出,这样就会触发Display解析换行:match foo() { Ok(val) => val, Err(err) => { eprintln!("{}", err); panic!(); // 或者根据需求终止程序/处理错误 } }自定义错误类型,让Debug复用Display的逻辑
把错误包装成自定义结构体,让它的Debug实现直接调用Display,这样unwrap()输出时就会解析换行:#[derive(Debug)] struct MyError(String); impl std::fmt::Display for MyError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.0) } } impl std::error::Error for MyError {} fn foo() -> Result<String, MyError> { Err(MyError("lorem\nipsum".to_string())) } fn main() { foo().unwrap(); // 现在会输出换行后的内容 }用unwrap_or_else配合panic!输出Display格式
写法更简洁的替代方式,通过unwrap_or_else捕获错误,然后用panic!("{}", err)输出:foo().unwrap_or_else(|err| panic!("{}", err));
内容的提问来源于stack exchange,提问作者Dalit Sairio
相关产品推荐
相关产品推荐

