模式匹配借来的内容问题

时间:2015-05-29 14:39:38

标签: rust

所以我有这段代码读取BULK INSERT TestTable FROM 'C:\CSVData\sheet1.xls' WITH ( FIRSTROW = 2, FIELDTERMINATOR = ',', --CSV field delimiter ROWTERMINATOR = '\n', --Use to shift the control to next row ERRORFILE = 'C:\CSVDATA\SchoolsErrorRows.txt', TABLOCK ) ,在其中插入一列并将其写入input.csv

output.csv

并且它给了我一个错误:

extern crate csv;

use std::path::Path;

struct User {
    reference: String,
    email: String,
    firstname: String,
    lastname: String
}

fn main() {

    let mut rdr = csv::Reader::from_file("/tmp/input.csv").unwrap().has_headers(false);
    let mut wtr = csv::Writer::from_file(Path::new("/tmp/output.csv")).unwrap();

    let users = get_users();

    for record in rdr.decode() {

        let rec: Option<Vec<String>> = match record {
            Ok(rec) => Some(rec),
            Err(e) => None
        };

        match rec {
            Some(mut r) => {
                let usr = users.iter().find(|&ur| ur.reference == r[27].to_string());
                match usr {
                    Some(u) => r.insert(1, u.email),
                    None => r.insert(1, "Unknown".to_string())
                }
                wtr.write(r.iter());
            }
            None => {}
        };

    }

}

fn get_users() -> Vec<User> {
    //retrieve users
}

所以我理解它对error: cannot move out of borrowed content Some(u) => r.insert(1, u.email), ^ 感到不满,因为u.email正试图取得它的所有权(?),但是如何最好地处理这种情况呢?

1 个答案:

答案 0 :(得分:4)

以下是代码的略微简化部分,用于演示问题:

struct User {
    reference: String,
    email: String
}

let users = vec![
    User { reference: "1".into(), email: "a@a.com".into() }, 
    User { reference: "2".into(), email: "b@b.com".into() }
];

let records: Vec<Vec<String>> = vec![
    vec!["1".into()], 
    vec!["2".into()], 
    vec!["3".into()]
];

for mut record in records {
    let usr = users.iter().find(|ur| ur.reference == record[0]);
    match usr {
        Some(u) => record.insert(1, u.email),
        None => record.insert(1, "Unknown".into())
    }
    // do whatever with record
}
usr中{p> let usr的类型为&User,而不是User,因为iter()返回满足Iterator<Item=&User>的迭代器,因此{ {1}}返回find()。因此,您无法从Option<&User>中取出String - 您无法退出借来的参考资料。这是BTW,一个绝对正确的错误 - 如果这是允许的话,你的代码会在具有与同一用户相对应的多个记录的情况下中断(它需要多次将电子邮件移出同一个用户)。

这里最自然的方式就是使用u: &User

clone()

它会创建找到的record.insert(1, u.email.clone()) 中包含的电子邮件字符串的副本,正是您所需要的。