Посмотрите на этот фрагмент кода:
let mut topics: HashMap<(&str, &str), &str> = HashMap::new();
for filename in files {
let mut rdr = csv::Reader::from_path(filename).unwrap();
for rec in rdr.records() {
let rr = rec.unwrap();
let value1 = rr.get(0).unwrap();
let value2 = rr.get(1).unwrap();
topics.insert((filename, value1), value2);
}
}
Он создает HashMap
, который содержит ссылки на некоторые строки, но кто является владельцем этих строк?Это rr
;таким образом, ваше сообщение об ошибке.
После кода:
Reader::from_path
читает CSV с диска, и rdr
владеет этим результатом.
Документация для Reader::records
гласит (выделено мое):
Возвращает заимствованный итератор сверхвсе записи в виде строк.
Таким образом, итератор не может пережить API Reader
.
StringRecord::get
:
pub fn get(&self, i: usize) -> Option<&str>
Возвращает строковую ссылку, которая живет только до тех пор, пока self
.
Путем отслеживания этой строки срезыВы пытаетесь вставить фактические справочные данные, принадлежащие StringRecord
.Эти записи удаляются в конце тела цикла for
, как показано в сообщении об ошибке.Это может привести к небезопасной памяти, что позволит вам иметь эти ссылки после цикла, поэтому компилятор останавливает вас.
Вставка String
s вместо этого позволяет коду продолжить:
topics.insert((filename, value1.to_owned()), value2.to_owned());
Я думал, что вставка в HashMap
передает право собственности
Да, это так.Право собственности на ссылки передается.Эти ссылки ссылаются не на
См. Также: