我正在尝试在 Rust 中实现一个简单的分桶哈希表(仅供练习)。哈希表结构定义为:
pub struct BucketedHashTable<K: Hash, V> {
buckets: Vec<Bucket<K, V>>,
size: usize,
}
Bucket
我对单链接堆栈的简单实现在哪里。
put
在表( , remove
, )的几乎所有方法中,get
我都将获取要插入密钥的存储桶(从中删除,查找),因此我为此提取了一个方法:
fn pick_bucket(&mut self, key: K) -> &mut Bucket<K, V> {
let mut hasher = DefaultHasher::new();
key.hash(&mut hasher);
let hash = hasher.finish() as usize;
let index = hash % self.buckets.len();
&mut self.buckets[index]
}
我返回对存储桶的引用,因为我不想将它移出buckets
哈希表的 Vec。我返回一个可变引用,因为我要改变返回的存储桶(例如,在向其中插入一个新条目(键值对)时)。
上面的代码可以编译。
但是,如果我去掉中间变量index
并计算[]
括号内的索引,如下所示:
fn pick_bucket(&mut self, key: K) -> &mut Bucket<K, V> {
let mut hasher = DefaultHasher::new();
key.hash(&mut hasher);
let hash = hasher.finish() as usize;
&mut self.buckets[hash % self.buckets.len()]
}
我会得到这个借用错误:
error[E0502]: cannot borrow `self.buckets` as immutable because it is also borrowed as mutable
--> src\lib.rs:30:34
|
26 | fn pick_bucket(&mut self, key: K) -> &mut Bucket<K, V> {
| - let's call the lifetime of this reference `'1`
...
30 | &mut self.buckets[hash % self.buckets.len()]
| -------------------------^^^^^^^^^^^^^^^^^^-
| | | |
| | | immutable borrow occurs here
| | mutable borrow occurs here
| returning this value requires that `self.buckets` is borrowed for `'1`
我认为上面的两个代码片段是等价的。它们有什么不同,为什么第一个编译,为什么第二个不编译?
编辑:我认为self.buckets
第一个代码片段中的不可变借用超出了范围,并在带有 的行的末尾“无效” let index = ...;
,因此当方法返回时,没有对self.buckets
left 的共享引用;在第二个片段中,self.buckets
生命的不可变借用直到方法返回(因此在那一刻共享和可变引用共存)。如果这是正确的,为什么会这样?为什么在第二种情况下self.buckets
到达]
括号时,不可变借用不会“无效”,而是为整个表达式(整个返回线)而存在?