file - 从文件中取出数字并放入 Vec但不断出错
问题描述
代码:
use std::io::Read;
fn main() {
let mut file = std::fs::File::open("numbs").unwrap();
let mut contents = String::new();
file.read_to_string(&mut contents).unwrap();
let mut v: Vec<i32> = Vec::new();
for s in contents.lines() {
v.push(s.parse::<i32>().unwrap());
}
}
错误:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ParseIntError { kind: Empty }', src/libcore/result.rs:1165:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
解决方案
最有可能的是,文件末尾有一个尾随换行符\n
,即最后一行是空的。您的文件中间可能还有空行。
为您的用例解决此问题的最简单方法是忽略空行:
for s in contents.lines() {
if !s.is_empty() {
v.push(s.parse::<i32>().unwrap());
}
}
但是,如果你不能保证它永远不会恐慌,那么只做unwrap
一个通常不是一个好主意。Result
一个更强大的解决方案是Result
适当地处理每个可能的结果。此解决方案的另一个优点是它不仅会忽略空行,还会忽略无法解析为i32
. 这是否是您想要的,或者您是否希望明确处理此错误取决于您。在下面的示例中,我们将使用 if-let 仅在将值成功解析为 时才将值插入到向量中i32
:
for s in contents.lines() {
if let Ok(i) = s.parse::<i32>() {
v.push(i);
}
}
旁注:您不需要将整个文件读入字符串然后逐行解析。请参阅在 Rust 中逐行读取大文件以了解如何更惯用地实现这一点
结合上述观点和 and 的使用flatten
,flat_map
我们可以将逻辑大大简化为:
use std::fs::File;
use std::io::{BufRead, BufReader};
fn main() {
let file = File::open("numbs").unwrap();
let v: Vec<i32> = BufReader::new(file)
.lines()
.flatten() // gets rid of Err from lines
.flat_map(|line| line.parse::<i32>()) // ignores Err variant from Result of str.parse
.collect();
}
推荐阅读
- sql - 当存在具有相同计数的多行时,如何使用 group by 选择具有最大计数的单行
- ssis - 父 - 子 SSIS 包执行
- javascript - 反应:TypeError:无法读取 null 的属性“innerHTML”
- sql - 替换 IBM DB2 SQL 中每个 ID 和每个月的值?
- c# - Box.com API 未返回文件夹中的所有项目列表
- javascript - onclick 只选择类中的一个元素
- android - kotlin 1.4.30 firebase crashlytics 问题
- reactjs - 找不到 package.json 文件
- path - 路径中的 iterm 跳转词
- delphi - 在 Delphi 中用自身的数组记录