尝试遍历网格结构会导致 "borrowed value does not live long enough"
Trying to iterate through a mesh structure results in "borrowed value does not live long enough"
我正在尝试创建一个可以存储监视器位置数据的数据结构。
我采用的方法是每个屏幕都有对存储在 HashMap<Direction, Rc<RefCell<Screen>>>
.
中的 4 个邻居的引用
我正在苦苦挣扎的是如何"move"/在一个方向上迭代直到我到达网格的边缘:
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
#[derive(Debug, Copy, Clone, Default)]
pub struct ScreenCoord {
left: i32,
right: i32,
bottom: i32,
top: i32,
}
impl ScreenCoord {
fn new_primary_from_dimensions(width: i32, height: i32) -> ScreenCoord {
ScreenCoord {
left: 0,
right: width,
top: 0,
bottom: height,
}
}
}
pub struct ScreenNetwork {
primary_screen: Rc<RefCell<Screen>>,
}
impl ScreenNetwork {
pub fn new(width: i32, height: i32) -> ScreenNetwork {
ScreenNetwork {
primary_screen: Rc::new(RefCell::new(Screen::new(
ScreenCoord::new_primary_from_dimensions(width, height),
))),
}
}
pub fn add_screen(&mut self, new_width: i32, new_height: i32, direction: Direction) {
let mut new_scrn = Screen::new(ScreenCoord::new_primary_from_dimensions(
new_width, new_height,
));
let mut original_screen = &self.primary_screen;
while let Some(next) = original_screen.borrow().neighbours.get(&direction) {
original_screen = next;
}
// Do stuff with original_screen
// new_scrn.neighbours.insert(Direction::from_u8((direction.clone() as u8) ^ 0b11).unwrap(), original_screen.clone());
// original_screen.borrow_mut().neighbours.insert(direction, Rc::new(RefCell::new(new_scrn)));
}
}
/// Screen with information about adjacent screens
#[derive(Default, Debug)]
pub struct Screen {
neighbours: HashMap<Direction, Rc<RefCell<Screen>>>,
coordinates: ScreenCoord,
}
impl Screen {
pub fn new(coord: ScreenCoord) -> Screen {
Screen {
coordinates: coord,
neighbours: HashMap::new(),
}
}
}
#[derive(Debug, PartialEq, Hash, Eq, Clone)]
pub enum Direction {
Left = 0,
Top,
Bottom,
Right,
}
fn main() {}
error[E0597]: borrowed value does not live long enough
--> src/main.rs:43:32
|
43 | while let Some(next) = original_screen.borrow().neighbours.get(&direction) {
| ^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value dropped here while still borrowed
| |
| temporary value does not live long enough
...
51 | }
| - temporary value needs to live until here
我明白错误发生的原因,但我不知道如何修复它。我尝试克隆 original_screen
和 next
,但随后编译器抱怨我在尝试设置 original_screen
的同时仍然借用它。
您正在使用 Rc
,请充分利用它。一般来说,引用一个Rc
就是自问自答
首先尝试:在需要时克隆 Rc
:
let mut original_screen = self.primary_screen.clone();
while let Some(next) = original_screen.borrow().neighbours.get(&direction) {
original_screen = next.clone();
}
失败并显示消息:
cannot assign to original_screen
because it is borrowed
确实如此:在 while
条件中借用不会让您更新它,但可以轻松重写:
loop {
if let Some(next) = original_screen.borrow().neighbours.get(&direction) {
original_screen = next.clone()
} else {
break;
}
}
该代码是等效的,并且确实失败并显示相同的错误消息!但现在我们离解决方案更近了:
loop {
let next = if let Some(next) = original_screen.borrow().neighbours.get(&direction) {
next.clone()
} else {
break;
};
original_screen = next;
}
现在可以编译了,因为赋值是在释放借用之后完成的。
我正在尝试创建一个可以存储监视器位置数据的数据结构。
我采用的方法是每个屏幕都有对存储在 HashMap<Direction, Rc<RefCell<Screen>>>
.
我正在苦苦挣扎的是如何"move"/在一个方向上迭代直到我到达网格的边缘:
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
#[derive(Debug, Copy, Clone, Default)]
pub struct ScreenCoord {
left: i32,
right: i32,
bottom: i32,
top: i32,
}
impl ScreenCoord {
fn new_primary_from_dimensions(width: i32, height: i32) -> ScreenCoord {
ScreenCoord {
left: 0,
right: width,
top: 0,
bottom: height,
}
}
}
pub struct ScreenNetwork {
primary_screen: Rc<RefCell<Screen>>,
}
impl ScreenNetwork {
pub fn new(width: i32, height: i32) -> ScreenNetwork {
ScreenNetwork {
primary_screen: Rc::new(RefCell::new(Screen::new(
ScreenCoord::new_primary_from_dimensions(width, height),
))),
}
}
pub fn add_screen(&mut self, new_width: i32, new_height: i32, direction: Direction) {
let mut new_scrn = Screen::new(ScreenCoord::new_primary_from_dimensions(
new_width, new_height,
));
let mut original_screen = &self.primary_screen;
while let Some(next) = original_screen.borrow().neighbours.get(&direction) {
original_screen = next;
}
// Do stuff with original_screen
// new_scrn.neighbours.insert(Direction::from_u8((direction.clone() as u8) ^ 0b11).unwrap(), original_screen.clone());
// original_screen.borrow_mut().neighbours.insert(direction, Rc::new(RefCell::new(new_scrn)));
}
}
/// Screen with information about adjacent screens
#[derive(Default, Debug)]
pub struct Screen {
neighbours: HashMap<Direction, Rc<RefCell<Screen>>>,
coordinates: ScreenCoord,
}
impl Screen {
pub fn new(coord: ScreenCoord) -> Screen {
Screen {
coordinates: coord,
neighbours: HashMap::new(),
}
}
}
#[derive(Debug, PartialEq, Hash, Eq, Clone)]
pub enum Direction {
Left = 0,
Top,
Bottom,
Right,
}
fn main() {}
error[E0597]: borrowed value does not live long enough
--> src/main.rs:43:32
|
43 | while let Some(next) = original_screen.borrow().neighbours.get(&direction) {
| ^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value dropped here while still borrowed
| |
| temporary value does not live long enough
...
51 | }
| - temporary value needs to live until here
我明白错误发生的原因,但我不知道如何修复它。我尝试克隆 original_screen
和 next
,但随后编译器抱怨我在尝试设置 original_screen
的同时仍然借用它。
您正在使用 Rc
,请充分利用它。一般来说,引用一个Rc
就是自问自答
首先尝试:在需要时克隆 Rc
:
let mut original_screen = self.primary_screen.clone();
while let Some(next) = original_screen.borrow().neighbours.get(&direction) {
original_screen = next.clone();
}
失败并显示消息:
cannot assign to
original_screen
because it is borrowed
确实如此:在 while
条件中借用不会让您更新它,但可以轻松重写:
loop {
if let Some(next) = original_screen.borrow().neighbours.get(&direction) {
original_screen = next.clone()
} else {
break;
}
}
该代码是等效的,并且确实失败并显示相同的错误消息!但现在我们离解决方案更近了:
loop {
let next = if let Some(next) = original_screen.borrow().neighbours.get(&direction) {
next.clone()
} else {
break;
};
original_screen = next;
}
现在可以编译了,因为赋值是在释放借用之后完成的。