HashMap中键引用值的生存时间

  • 本文关键字:时间 引用 HashMap rust
  • 更新时间 :
  • 英文 :


我对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 OWN值时,它就不起作用了:

println!("{:?}", map_by(foos,        |f| f.name.as_str()));
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements

不幸的是,错误信息融化了我的大脑。我尝试指定键和值具有相同的生存期,但没有帮助。它在操场上。编译器试图告诉我什么,我做错了什么?当然,如果这在我们借用价值观时有效,那么在我们拥有价值观时也有效。

当然,如果当我们借用值时这可以工作,那么当我们拥有它们时它也可以工作。

否。当HashMap需要调整自身大小以适应新条目时,它会在内存中移动条目。如果密钥借用了该值,并且条目被移动,则该值的地址将更改,密钥中的引用将不再有效。

有关更多信息,请参阅Why can';我是否将一个值和对该值的引用存储在同一个结构中?。

最新更新