我最近开始学习Rust,在编写一个测试程序时,我写了这个方法:
pub fn add_transition(&mut self, start_state: u32, end_state: u32) -> Result<bool, std::io::Error> {
let mut m: Vec<Page>;
let pages: &mut Vec<Page> = match self.page_cache.get_mut(&start_state) {
Some(p) => p,
None => {
m = self.index.get_pages(start_state, &self.file)?;
&mut m
}
};
// omitted code that mutates pages
// ...
Ok(true)
}
代码可以正常工作,但我对m
变量并不满意。如果我移除它,代码会更加简洁:
pub fn add_transition(&mut self, start_state: u32, end_state: u32) -> Result<bool, std::io::Error> {
let pages: &mut Vec<Page> = match self.page_cache.get_mut(&start_state) {
Some(p) => p,
None => &mut self.index.get_pages(start_state, &self.file)?
};
// omitted code that mutates pages
// ...
Ok(true)
}
但是我得到的是:
error[E0716]: temporary value dropped while borrowed
--> src\module1\mod.rs:28:29
|
26 | let pages: &mut Vec<Page> = match self.page_cache.get_mut(&start_state) {
| _____________________________________-
27 | | Some(p) => p,
28 | | None => &mut self.index.get_pages(start_state, &self.file)?
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| | | |
| | | temporary value is freed at the end of this statement
| | creates a temporary which is freed while still in use
29 | | };
| |_________- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
我完全理解这个错误,它引导我到工作的片段,但我想知道是否有更优雅和/或成语化的编写此代码的方式。我在函数开始时声明了
m
,只是为了防止临时变量过早释放。有没有办法告诉编译器self.index.get_pages
的返回值的生命周期应该是整个add_transition
函数?进一步细节:
-
Page
是一个相对较大的结构体,因此我不想实现Copy
特性,也不想克隆它。
- page_cache
的类型是HashMap<u32, Vec<Page>>
- self.index.get_pages
相对较慢,我正在使用page_cache
来缓存结果
- self.index.get_pages
的返回类型是Result<Vec<Page>, std::io::Error>