问题描述
(Rust 新手,仅供参考!)
所以 - 我一直试图在 Rust 中理解生命周期的概念。我已经阅读了文档,并阅读了一些关于该主题的博客和 SO 帖子。但仍然没有完全明白(因此,这个问题的标题可能不好)。
我有一个特别的问题,我想弄清楚,我已经将其归结为这个小示例代码(试图尽可能接近工作示例):
use std::collections::HashMap;
// Imagine this is actually a more complex type:
type BigComplexType = i32;
fn some_expensive_computation() -> BigComplexType {
// Imagine this takes some arguments,and takes a long time to run
return 123;
}
fn construct() -> HashMap<i32,&'static HashMap<i32,BigComplexType>> {
let mut main = HashMap::new();
let mut nested = HashMap::new();
nested.insert(1111,some_expensive_computation());
nested.insert(2222,some_expensive_computation());
// ... and lots more inserts...
main.insert(10,&nested);
main.insert(20,&nested);
// ... and lots more inserts...
// Imagine a lot more other nested HashMaps to follow here
// let mut nested2 = ...
// ...
// main.insert(...,&nested2);
// ...
return main;
}
fn main() {
construct();
}
这个例子有点琐碎 - 在实际代码中,我在 construct()
函数中创建了更复杂和更深层次的结构。
我想要做的是创建某种缓存来保存这些预先计算的值,以便可以在代码中的其他地方轻松快速地访问它们。也许这一切都可以以某种完全不同的方式完成 - 但我认为必须有一种方法可以做到这一点。
但是,rustc
在这里抱怨,因为nested
只存在于construct()
中,一旦我们退出函数,它就不存在了,因此所有的引用都是无效的(或者,这就是我对问题的理解)。
我尝试为 'a
函数引入 construct()
生命周期,并在下面的 nested
HashMap 上使用该生命周期,但没有骰子。遇到了一些错误,并且永远无法使其完全发挥作用。我尝试了各种添加生命周期注释的变体,但没有骰子。
我有一种感觉,我只是没有在这里理解整个概念的某些方面。谁能帮我指明正确的方向?
(我确实考虑过将 nested
HashMap 收集到一个向量中并沿着 main
哈希图返回 - 这样该函数就会返回主 HashMap 以及嵌套的向量 -因此,寿命将得到保证,我认为 - 但我在尝试时遇到了其他一些障碍,并且感觉我把事情复杂化了。)
error[E0515]: cannot return value referencing local variable `nested`
--> lifetime_return.rs:29:12
|
19 | main.insert(10,&nested);
| ------- `nested` is borrowed here
...
29 | return main;
| ^^^^ returns a value referencing data owned by the current function
error[E0515]: cannot return value referencing local variable `nested`
--> lifetime_return.rs:29:12
|
20 | main.insert(20,&nested);
| ------- `nested` is borrowed here
...
29 | return main;
| ^^^^ returns a value referencing data owned by the current function
error: aborting due to 2 prevIoUs errors
For more information about this error,try `rustc --explain E0515`.
任何/所有帮助将不胜感激!我试图寻找类似的问题,但找不到一个 - 也许我只是没有将某些 SO 帖子识别为重复,因为我还没有完全理解生命周期模型。
解决方法
您对为什么这不起作用的直觉是正确的:nested
只存在于 construct
内,并且您尝试在哈希图中返回对它的引用,该引用的存在时间比函数长。假设您不想克隆嵌套映射,大概是因为它们非常大,您可以使用 Rc
代替作为对嵌套映射进行简单可克隆的引用的一种方式,这些引用使它们保持活动状态必要的:
use std::collections::HashMap;
use std::rc::Rc;
type BigComplexType = i32;
fn some_expensive_computation() -> BigComplexType {
return 123;
}
fn construct() -> HashMap<i32,Rc<HashMap<i32,BigComplexType>>> {
let mut main = HashMap::new();
let mut nested = HashMap::new();
nested.insert(1111,some_expensive_computation());
nested.insert(2222,some_expensive_computation());
let nested_rc = Rc::new(nested);
main.insert(10,Rc::clone(&nested_rc));
main.insert(20,nested_rc); // can move the Rc for the last insert
let mut nested2 = HashMap::new();
nested2.insert(3333,some_expensive_computation());
nested2.insert(4444,some_expensive_computation());
let nested2_rc = Rc::new(nested2);
main.insert(30,Rc::clone(&nested2_rc));
main.insert(40,nested2_rc);
return main;
}
fn main() {
let map = construct();
println!("{}",map[&10][&1111]); // 123
}