Я относительно новичок в Rust. Я хочу написать функцию, которая будет создавать HashMap из коллекции с заданным замыканием, которое генерирует ключ из значения, например,
[derive(Debug)]
struct Foo {
id: u32,
name: String,
}
let foos = vec![
Foo { id: 1, name: "Bill".to_string() },
Foo { id: 2, name: "Mary".to_string() },
];
println!("{:?}", foos);
println!("{:?}", map_by(foos.iter(), |f| f.id)); // borrow the Foos
println!("{:?}", map_by(foos.iter(), |f| &f.name)); // borrow
println!("{:?}", map_by(foos.iter(), |f| f.name.as_str())); // borrow
println!("{:?}", map_by(foos, |f| f.id)); // consume the Foos
Я написал это, и это работает для вышеуказанного использования:
fn map_by<I,K,V>(iterable: I, f: impl Fn(&V) -> K) -> HashMap<K,V>
where I: IntoIterator<Item = V>,
K: Eq + Hash
{
iterable.into_iter().map(|v| (f(&v), v)).collect()
}
[Foo { id: 1, name: "Bill" }, Foo { id: 2, name: "Mary" }]
{1: Foo { id: 1, name: "Bill" }, 2: Foo { id: 2, name: "Mary" }}
{"Bill": Foo { id: 1, name: "Bill" }, "Mary": Foo { id: 2, name: "Mary" }}
{"Bill": Foo { id: 1, name: "Bill" }, "Mary": Foo { id: 2, name: "Mary" }}
{2: Foo { id: 2, name: "Mary" }, 1: Foo { id: 1, name: "Bill" }}
Отлично! Но это не работает, когда я позволяю HashMap СОБСТВЕННО значениям, когда ключи ссылаются на них:
println!("{:?}", map_by(foos, |f| f.name.as_str()));
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
И, к сожалению, сообщение об ошибке растопило мой мозг. Я попытался указать, что ключ и значение имеют одинаковое время жизни, но это не помогло. Вот она на детской площадке . Что компилятор пытается мне сказать, и что я делаю не так? Конечно, если это может работать, когда мы заимствуем значения, оно может работать, когда мы владеем ими.