Closure issues when using dereference

Hey guys I have this code:

fn hours_working_choice(hours_working: &mut u8)
{
    let hours_choices = [6u8, 8];

    let mut dropdown = menu::Choice::default()
    .with_size(80, 30)
    .with_label("Select hours working for today");

    dropdown.set_pos(WINDOW_SIZE.w/2, 20);

    for hours_choice in hours_choices.iter()
    {
        dropdown.add_choice(&format!("{}", hours_choice));
    }
    //dropdown.add_choice("6");
    //dropdown.add_choice("8");

    dropdown.set_callback(move |c|
    {
        for (i, hours_choice) in hours_choices.iter().enumerate()
        {
            if i == c.value() as usize
            {
                *hours_working = *hours_choice;
                break;
            }
        }
    });
}

and I am getting this error:

error[E0521]: borrowed data escapes outside of function
  --> src/main.rs:58:5
   |
41 |   fn hours_working_choice(hours_working: &mut u8)
   |                           -------------  - let's call the lifetime of this reference `'1`
   |                           |
   |                           `hours_working` is a reference that is only valid in the function body
...
58 | /     dropdown.set_callback(move |c|
59 | |     {
60 | |         for (i, hours_choice) in hours_choices.iter().enumerate()
61 | |         {
...  |
67 | |         }
68 | |     });
   | |      ^
   | |      |
   | |______`hours_working` escapes the function body here
   |        argument requires that `'1` must outlive `'static`

I am using fltk-rs by the way

What should I change with this to do this inside the closure?

The closure must be 'static, so you can't capture the &mut or any other (non-'static) borrow.

Probably you need some sort of shared ownership like an Arc<Mutex<_>> or Arc<AtomicU8>.

Here is part of my code in some other project using egui:

fn directory_singleline(filepath_singleline: &mut String, starting_dir: Option<&str>, file_picker_mode: radio_options::FilePickerMode, make_relative: bool, ui: &mut Ui, emojis: &Emojis) -> (Response, bool)
{
    use radio_options::FilePickerMode;
    // bool return is to determine if file dir has been selected
    let mut selected_file = false;

    let mut response: Option<Response> = None;
    ui.horizontal(|ui|
    {
        response = Some(ui.add(egui::TextEdit::singleline(filepath_singleline)));
        if ui.button(format!("{}", emojis.file_icons.folder)).clicked()
        {
            let starting_dir = match starting_dir
            {
                Some(value) => value.to_string(),
                None =>
                {
                    match dirs::home_dir()
                    {
                        Some(value) => value.display().to_string(),
                        None => "/".to_string(),
                    }
                }
            };
            let mut path_picked: Option<PathBuf> = None;

            match file_picker_mode
            {
                FilePickerMode::OpenFolder => path_picked = FileDialog::new().set_directory(&starting_dir).pick_folder(),
                FilePickerMode::OpenFile => path_picked = FileDialog::new().set_directory(&starting_dir).pick_file(),
                FilePickerMode::SaveFile(_) => path_picked = FileDialog::new().set_directory(&starting_dir).save_file(),
            }
            /*
            if is_file == true
            {
                path_picked = FileDialog::new().set_directory(&starting_dir).pick_file();
            }
            else
            {
                path_picked = FileDialog::new().set_directory(&starting_dir).pick_folder();
            }
            */
            match path_picked
            {
                //invert_pathtype(&flameobject_settings.texture.file_location, &projects);
                //Some(value) => *filepath_singleline = value.display().to_string(),
                Some(value) =>
                {
                    selected_file = true;
                    if make_relative == true
                    {
                        *filepath_singleline = invert_pathtype(&value.display().to_string(), &starting_dir);

See how in the last line I am using pointers and stuff, why is this not a problem in egui but it is in fltk-rs, you can see I am clearly using a closure over here ui.horizontal(|ui|.

Sorry I don't know enough about this and I am curious to know why this may be the case before I try your suggested code.

That egui method doesn't have a 'static requirement.

Different libraries have different designs. I'm an expert in neither of these, so I can't speak to why they're designed how they are.

1 Like

Do you by any chance know something that is similar to egui but it is retained graphics?

I don't, sorry.