模式匹配借用内容问题

4

我有一段代码,它会读取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感到不安,因为r试图取得它的所有权(?), 但如何最好地处理这种情况呢?

1个回答

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
}

在“let usr”中,“usr”的类型是“&User”,而不是“User”,因为“iter()”返回满足“Iterator ”的迭代器,因此“find()”返回“Option <&User>”。因此,您不能从“u:&User”中取出“String” - 您无法移动借用的引用。顺便说一下,这是绝对正确的错误 - 如果允许这样做,则在多个记录对应于同一用户的情况下,您的代码将会出错(它将需要多次从同一用户中提取电子邮件)。
在这里最自然的方法就是使用“clone()”:
record.insert(1, u.email.clone())

它将创建一个电子邮件字符串的副本,该字符串包含在找到的User中,这正是您所需的。


谢谢,u.email.clone() 正是我所需要的。 - Caballero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接