简体   繁体   English

返回值的 Rust 寿命问题

[英]Problem with Rust lifetime of a return value

Apologies for the following question.为以下问题道歉。 The compiler says that a temporary is created which is freed while still in use.编译器说创建了一个临时文件,该临时文件在仍在使用时被释放。

What I was trying to do is an example from the Rust book at https://doc.rust-lang.org/book/ch13-01-closures.html in which a Closure is supposed to update a HashMap in case the searched key is not found. What I was trying to do is an example from the Rust book at https://doc.rust-lang.org/book/ch13-01-closures.html in which a Closure is supposed to update a HashMap in case the searched key没有找到。

How can make this code compilable?如何使这段代码可编译? Playground : 游乐场

Every time I edit the code new errors arise, even following recommendations from the compiler.每次我编辑代码时都会出现新的错误,即使遵循编译器的建议也是如此。

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)
            );
        }
    }
}

Thank you in advance,先感谢您,

There's absolutely no reason to store references to u32 s in a HashMap .绝对没有理由将HashMap u32 Just store the values themselves and your problems should disappear.只需存储值本身,您的问题就会消失。 Just doing that made everything compile just fine:只是这样做使一切编译得很好:

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)
            );
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM