return 值的 Rust 生命周期问题
Problem with Rust lifetime of a return value
对于以下问题深表歉意。编译器说创建了一个临时文件,它在仍在使用时被释放。
我试图做的是来自 https://doc.rust-lang.org/book/ch13-01-closures.html 的 Rust 书中的一个示例,其中闭包应该更新 HashMap,以防找不到搜索到的键。
如何使这段代码可编译? Playground:
每次我编辑代码时都会出现新的错误,即使遵循编译器的建议也是如此。
use std::thread;
use std::time::Duration;
use std::collections::HashMap;
fn main() {
let simulated_user_specified_value = 10;
let simulated_random_number = 7;
generate_workout(simulated_user_specified_value, simulated_random_number);
let simulated_user_specified_value = 10;
let simulated_random_number = 7;
generate_workout(simulated_user_specified_value, simulated_random_number);
let simulated_user_specified_value = 50;
let simulated_random_number = 12;
generate_workout(simulated_user_specified_value, simulated_random_number);
}
struct Cacher<'a, T>
where
T: Fn(u32) -> u32,
{
calculation: T,
value: HashMap<&'a u32, &'a u32>,
}
impl<'a, T> Cacher<'a, T>
where
T: Fn(u32) -> u32,
{
fn new(calculation: T) -> Cacher<'a, T> {
Cacher {
calculation,
value: HashMap::new(),
}
}
fn value(&mut self, arg: &'a u32) -> &'a u32 {
println!("{:?}", arg);
self.value.entry(&arg).or_insert(&(self.calculation)(30))
}
}
fn generate_workout(intensity: u32, random_number: u32) {
let mut expensive_result = Cacher::new(|num| -> u32 {
println!("calculating slowly...");
thread::sleep(Duration::from_secs(2));
num
});
if intensity < 25 {
println!("Today, do {} pushups!", expensive_result.value(&intensity));
println!("Next, do {} situps!", expensive_result.value(&intensity));
} else {
if random_number == 3 {
println!("Take a break today! Remember to stay hydrated!");
} else {
println!(
"Today, run for {} minutes!",
expensive_result.value(&intensity)
);
}
}
}
提前谢谢你,
绝对没有理由在 HashMap
中存储对 u32
的引用。只需存储值本身,您的问题就会消失。只要这样做就可以让一切都编译得很好:
use std::thread;
use std::time::Duration;
use std::collections::HashMap;
fn main() {
let simulated_user_specified_value = 10;
let simulated_random_number = 7;
generate_workout(simulated_user_specified_value, simulated_random_number);
let simulated_user_specified_value = 10;
let simulated_random_number = 7;
generate_workout(simulated_user_specified_value, simulated_random_number);
let simulated_user_specified_value = 50;
let simulated_random_number = 12;
generate_workout(simulated_user_specified_value, simulated_random_number);
}
struct Cacher<T>
where
T: Fn(u32) -> u32,
{
calculation: T,
value: HashMap<u32, u32>,
}
impl<T> Cacher<T>
where
T: Fn(u32) -> u32,
{
fn new(calculation: T) -> Cacher<T> {
Cacher {
calculation,
value: HashMap::new(),
}
}
fn value(&mut self, arg: u32) -> u32 {
println!("{:?}", arg);
*self.value.entry(arg).or_insert((self.calculation)(30))
}
}
fn generate_workout(intensity: u32, random_number: u32) {
let mut expensive_result = Cacher::new(|num| -> u32 {
println!("calculating slowly...");
thread::sleep(Duration::from_secs(2));
num
});
if intensity < 25 {
println!("Today, do {} pushups!", expensive_result.value(intensity));
println!("Next, do {} situps!", expensive_result.value(intensity));
} else {
if random_number == 3 {
println!("Take a break today! Remember to stay hydrated!");
} else {
println!(
"Today, run for {} minutes!",
expensive_result.value(intensity)
);
}
}
}
对于以下问题深表歉意。编译器说创建了一个临时文件,它在仍在使用时被释放。
我试图做的是来自 https://doc.rust-lang.org/book/ch13-01-closures.html 的 Rust 书中的一个示例,其中闭包应该更新 HashMap,以防找不到搜索到的键。
如何使这段代码可编译? Playground:
每次我编辑代码时都会出现新的错误,即使遵循编译器的建议也是如此。
use std::thread;
use std::time::Duration;
use std::collections::HashMap;
fn main() {
let simulated_user_specified_value = 10;
let simulated_random_number = 7;
generate_workout(simulated_user_specified_value, simulated_random_number);
let simulated_user_specified_value = 10;
let simulated_random_number = 7;
generate_workout(simulated_user_specified_value, simulated_random_number);
let simulated_user_specified_value = 50;
let simulated_random_number = 12;
generate_workout(simulated_user_specified_value, simulated_random_number);
}
struct Cacher<'a, T>
where
T: Fn(u32) -> u32,
{
calculation: T,
value: HashMap<&'a u32, &'a u32>,
}
impl<'a, T> Cacher<'a, T>
where
T: Fn(u32) -> u32,
{
fn new(calculation: T) -> Cacher<'a, T> {
Cacher {
calculation,
value: HashMap::new(),
}
}
fn value(&mut self, arg: &'a u32) -> &'a u32 {
println!("{:?}", arg);
self.value.entry(&arg).or_insert(&(self.calculation)(30))
}
}
fn generate_workout(intensity: u32, random_number: u32) {
let mut expensive_result = Cacher::new(|num| -> u32 {
println!("calculating slowly...");
thread::sleep(Duration::from_secs(2));
num
});
if intensity < 25 {
println!("Today, do {} pushups!", expensive_result.value(&intensity));
println!("Next, do {} situps!", expensive_result.value(&intensity));
} else {
if random_number == 3 {
println!("Take a break today! Remember to stay hydrated!");
} else {
println!(
"Today, run for {} minutes!",
expensive_result.value(&intensity)
);
}
}
}
提前谢谢你,
绝对没有理由在 HashMap
中存储对 u32
的引用。只需存储值本身,您的问题就会消失。只要这样做就可以让一切都编译得很好:
use std::thread;
use std::time::Duration;
use std::collections::HashMap;
fn main() {
let simulated_user_specified_value = 10;
let simulated_random_number = 7;
generate_workout(simulated_user_specified_value, simulated_random_number);
let simulated_user_specified_value = 10;
let simulated_random_number = 7;
generate_workout(simulated_user_specified_value, simulated_random_number);
let simulated_user_specified_value = 50;
let simulated_random_number = 12;
generate_workout(simulated_user_specified_value, simulated_random_number);
}
struct Cacher<T>
where
T: Fn(u32) -> u32,
{
calculation: T,
value: HashMap<u32, u32>,
}
impl<T> Cacher<T>
where
T: Fn(u32) -> u32,
{
fn new(calculation: T) -> Cacher<T> {
Cacher {
calculation,
value: HashMap::new(),
}
}
fn value(&mut self, arg: u32) -> u32 {
println!("{:?}", arg);
*self.value.entry(arg).or_insert((self.calculation)(30))
}
}
fn generate_workout(intensity: u32, random_number: u32) {
let mut expensive_result = Cacher::new(|num| -> u32 {
println!("calculating slowly...");
thread::sleep(Duration::from_secs(2));
num
});
if intensity < 25 {
println!("Today, do {} pushups!", expensive_result.value(intensity));
println!("Next, do {} situps!", expensive_result.value(intensity));
} else {
if random_number == 3 {
println!("Take a break today! Remember to stay hydrated!");
} else {
println!(
"Today, run for {} minutes!",
expensive_result.value(intensity)
);
}
}
}