I'm trying to import a CSV file using the csv
crate,但问题是某些字段包含非UTF8值,因此我遇到运行时恐慌:
thread '<main>' panicked at 'called `Result::unwrap()` on an `Err` value: Decode("Could not convert bytes \'FromUtf8Error { bytes: [75, 108, 105, 110, 63, 101, 107, 111, 118, 225], error: Utf8Error { valid_up_to: 9 } }\' to UTF-8.")', /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libcore/result.rs:729
这就是我的代码的样子:
extern crate csv;
fn main() {
let mut rdr = csv::Reader::from_file("data.csv").unwrap();
for record in rdr.decode() {
let rec: Vec<String> = record.unwrap();
println!("{}", rec[0]);
}
}
我想以某种方式错误处理这种恐慌情况,所以我想知道我是否应该使用try!
宏?像这样:
let rec: Vec<String> = try!(record.unwrap());
当然这会产生错误
error: the trait `rustc_serialize::serialize::Decodable` is not implemented for the type `core::result::Result<_, _>` [E0277]
正确的语法是什么?
答案 0 :(得分:5)
您面临两个问题:
try!
宏的工作方式try!
main
醇>
try!
macro非常简单。它只是查看参数是否为Result::Err
。如果是,则从当前函数返回错误。如果参数是Result::Ok
,则提取内部值并且是评估try!
的结果。请注意,参数必须始终为Result
类型。
第二个问题是main
被定义为不返回任何值。这意味着你不能在main中使用try!
,因为try!
想要返回一个值。相反,您需要以“手动”的方式处理错误:
extern crate csv;
fn main() {
let mut rdr = match csv::Reader::from_file("data.csv") {
Ok(file) => file,
Err(e) => println!("Put nicer error handling here"),
};
for record in rdr.decode() {
let rec: Vec<String> = match record {
Ok(rec) => rec,
Err(e) => println!("Put nicer error handling here"),
};
println!("{}", rec[0]);
}
}
我想以某种方式错误处理恐慌情况
这是一种常见的误解。您无法处理恐慌。它们不是例外(Rust没有例外)。恐慌意味着线程死亡。你能做的最好的事情是产生一个线程并处理该线程的死亡。你真的没有做任何具体的事情。这就是Result
类型的全部内容。 Result::unwrap
和Option::unwrap
的方法意味着“如果不是{Ok
,Some
},那么现在就恐慌”。