【问题标题】:Problem with Rust lifetime of a return value返回值的 Rust 生命周期问题
【发布时间】:2021-05-31 09:08:29
【问题描述】:

对以下问题表示歉意。编译器说创建了一个临时文件,该临时文件在仍在使用时被释放。

我试图做的是来自 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)
            );
        }
    }
}

提前谢谢你,

【问题讨论】:

    标签: rust hashmap lifetime


    【解决方案1】:

    绝对没有理由将u32s 的引用存储在HashMap 中。只需存储值本身,您的问题就会消失。这样做就可以使一切编译得很好:

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

    【讨论】:

    • 我做到了,但出现了新的错误。除非要求,否则我不想用编译器错误淹没线程。谢谢。
    • @frencis1 对我来说很好用:play.rust-lang.org/….
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    • 2019-05-22
    • 2013-07-03
    • 1970-01-01
    • 2013-02-23
    • 1970-01-01
    相关资源
    最近更新 更多