我有以下内容:
use std::collections::HashMap;
use std::*;
fn main() {
let mut struct_a: struct_A = struct_A::new();
loop {
let _res = struct_a.process();
}
}
pub struct struct_A<'a> {
pub entities: struct_B<'a>,
}
impl<'a> struct_A<'a> {
pub fn new() -> struct_A<'a> {
let mut struct_A: struct_A = struct_A {
entities: struct_B::new(),
};
struct_A
}
pub fn process(&mut self) -> Result<(), String> {
self.entities.get_connection(832);
Ok(())
}
}
pub struct struct_B<'a> {
chain: Chain<u32, struct_c<'a>>,
}
pub struct struct_c<'a> {
// other fields here
u: &'a u32,
}
impl<'a> struct_B<'a> {
pub fn new() -> Self {
let cache = HashMap::new();
struct_B {
chain: Chain::<u32, struct_c>::new(cache),
}
}
pub fn get_connection(&self, mac: u32) -> Option<&'a mut Node<struct_c>> {
self.chain.find(mac)
}
}
pub struct Chain<K, V> {
pub cache: HashMap<K, *mut Node<V>>,
}
#[derive(Default)]
pub struct Node<T> {
pub data: T,
}
impl<K, V> Chain<K, V>
where
K: std::cmp::Eq + std::hash::Hash,
{
pub fn new(pool: HashMap<K, *mut Node<V>>) -> Self {
Chain { cache: pool }
}
pub fn find(&self, key: K) -> Option<&mut Node<V>> {
if let Some(node) = self.cache.get(&key) {
unsafe {
return Some(node.as_mut().unwrap());
}
}
None
}
}
编译,我得到:
error[E0499]: cannot borrow `struct_a` as mutable more than once at a time
--> src/main.rs:7:20
|
当我编译时,我得到:
--> src/main.rs:25:9
|
15 | impl<'a> struct_A<'a> {
| -- lifetime `'a` defined here
...
24 | pub fn process(&mut self) -> Result<(), String> {
| - let's call the lifetime of this reference `'1`
25 | self.entities.get_connection(832);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'a`
如果我给process()
加上生命周期,就像这样:
pub fn process<'b>(&'b mut self) -> Result<(), String>
where
'b: 'a,
{
self.entities.get_connection(832);
Ok(())
}
编译,我得到:
error[E0499]: cannot borrow `struct_a` as mutable more than once at a time
--> src/main.rs:7:20
|
7 | let _res = struct_a.process();
| ^^^^^^^^^^^^^^^^^^
| |
| `struct_a` was mutably borrowed here in the previous iteration of the loop
| first borrow used here, in later iteration of loop
我真的很难理解为什么我得到了原来的编译错误,开始,我认为这与variance
有关,但我不确定到底是什么。
1条答案
按热度按时间tvmytwxo1#
您的
get_connection
返回列表中为'a
生存的节点的可变引用,在本例中,这基本上是列表的整个生存期。这也强制get_connection
的&self
引用至少要借用'a
。现在在
process
中,您引用self.entities
并调用get_connection
。由于上述原因,必须借用此引用至少'a
。因此,process
中的整个&mut self
引用必须至少存在'a
。这是你得到的第一个错误,因为它不能保证。添加
&'b mut self where 'b: 'a
约束“解决”了这个问题,因为process
现在可以借用足够长的时间。但这仍然是不正确的。在main中,
struct_a
至少与循环一样长。所以这里的'a
参数对应于代码中的实际生存期:因此
struct_A::new
创建了一个struct_B
示例,该示例的生存期必须至少与包含struct_a
的示例的生存期一样长,将'a
设置为struct_a
的生存期。然后,每个对process
的调用必须借用 * 至少 *'a
,可变的。因此,循环的每次迭代都必须在其整个生命周期内可变地借用struct_a
,这是不可能的,因为一次只能存在一个可变引用。根据您提供的代码,
process
没有理由接受可变引用,因为它不会改变任何东西。如果你把这个引用改为&'b self where 'b: 'a
,一切都能正常工作并编译。在整个循环期间,引用仍然被采用,但由于它们是不可变的,因此它们可以共存。请参见in playground。