Rust迭代器collect生成集合时如何将解析错误转为Box<dyn Error>
错误原因
line.parse::<i32>()返回的错误类型是ParseIntError,而函数返回值要求的错误类型是Box<dyn Error>。你之前写的fs::read_to_string(filename)?能自动完成错误转换,是因为?运算符会隐式调用错误类型的into()方法做类型适配,但你直接把Result<i32, ParseIntError>的迭代器传给collect()时,Rust不会自动为每个错误做类型转换,因此出现类型不匹配。
解决方案
你猜测的方向是对的,确实需要用map_err做错误转换。所有实现了Error trait + 'static生命周期的类型,都可以通过into()方法自动包装为Box<dyn Error>,只需要在parse()调用后追加map_err(Into::into)即可。
修正后代码
use std::error::Error; use std::fs; pub fn read_file_to_list(filename: &str) -> Result<Vec<i32>, Box<dyn Error>> { let file_as_string = fs::read_to_string(filename)?; file_as_string.lines().map(|line| line.parse().map_err(Into::into)).collect() }
泛型适配提示
如果你后续要改成泛型实现,只需要补充对应的类型约束即可,参考示例:
use std::error::Error; use std::fs; use std::str::FromStr; pub fn read_file_to_list<T>(filename: &str) -> Result<Vec<T>, Box<dyn Error>> where T: FromStr, T::Err: Error + 'static, { let file_as_string = fs::read_to_string(filename)?; file_as_string.lines().map(|line| line.parse().map_err(Into::into)).collect() }
其中T::Err: Error + 'static的约束,是保证解析产生的错误可以被正常包装为Box<dyn Error>。
内容的提问来源于stack exchange,提问作者cadolphs
相关产品推荐
相关产品推荐

