Rust按BankType反序列化CSV遇类型不匹配错误,求原因
问题分析与解决
错误原因
Rust是静态类型语言,编译器会在编译阶段确定每个变量的具体类型。你的代码里,reader.deserialize()是泛型方法,当你在BankType::Citi分支把record赋值给Result<CitiRec, csv::Error>类型变量时,编译器直接推断整个for循环中record的类型就是Result<CitiRec, csv::Error>。到BankType::Kasaka分支时,你试图把已经固定类型的record转成Result<KasakaRec, csv::Error>,自然会触发类型不匹配错误——编译器已经认定record只能是CitiRec的结果类型,不可能是KasakaRec的。
解决方案
把deserialize()的调用放到每个match分支内部,让编译器在不同分支中推断出不同的泛型类型:
pub fn get_uncat_rec(path: &PathBuf, bank_type: BankType) -> Vec<UnCatRecord> { let mut reader = csv::Reader::from_path(path).unwrap(); let mut uncat_rec: Vec<UnCatRecord> = Vec::new(); match bank_type { BankType::Citi => { for record in reader.deserialize() { match record { Ok(rec) => uncat_rec.push(rec.to_uncat_rec()), Err(err) => println!("Error deserializing Citi Record: {}", err), } } } BankType::Kasaka => { for record in reader.deserialize() { match record { Ok(rec) => uncat_rec.push(rec.to_uncat_rec()), Err(err) => println!("Error deserializing Kasaka Record: {}", err), } } } _ => {} } uncat_rec }
如果想避免重复代码,可以用trait抽象转换逻辑:
首先定义统一转换的trait:
use serde::de::DeserializeOwned; trait ToUnCatRecord { fn to_uncat_rec(self) -> UnCatRecord; } // 为CitiRec实现转换逻辑 impl ToUnCatRecord for CitiRec { fn to_uncat_rec(self) -> UnCatRecord { // 填写你的转换代码 } } // 为KasakaRec实现转换逻辑 impl ToUnCatRecord for KasakaRec { fn to_uncat_rec(self) -> UnCatRecord { // 填写你的转换代码 } }
然后编写通用处理函数:
fn process_records<T: DeserializeOwned + ToUnCatRecord>( reader: csv::Reader<std::fs::File>, uncat_rec: &mut Vec<UnCatRecord> ) { for record in reader.deserialize() { match record { Ok(rec) => uncat_rec.push(rec.to_uncat_rec()), Err(err) => println!("Error deserializing record: {}", err), } } } pub fn get_uncat_rec(path: &PathBuf, bank_type: BankType) -> Vec<UnCatRecord> { let mut reader = csv::Reader::from_path(path).unwrap(); let mut uncat_rec: Vec<UnCatRecord> = Vec::new(); match bank_type { BankType::Citi => process_records::<CitiRec>(reader, &mut uncat_rec), BankType::Kasaka => process_records::<KasakaRec>(reader, &mut uncat_rec), _ => {} } uncat_rec }
内容的提问来源于stack exchange,提问作者Zach W
相关产品推荐
相关产品推荐

