You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 10:25:12