rustmutable-reference

Use `&mut Option<PathBuf>` on each iteration of loop


I have a situation where I have an Option<PathBuf> and I want to pass a mutable reference to it to a function (do_loop) and within that function it is passed to a second function (handle_path) within in each iteration of a loop. The second function also possibily calls the first function (so this is recursive).
I have attempted to create minimal example from my codebase which hopefully better illustrates what I am trying to achieve. I have tried using &mut Option<PathBuf>, &Option<&mut PathBuf>, and Option<&mut PathBuf> but none have worked. I could solve the problem by cloning the PathBuf at some point but I am hoping to avoid this in order to improve the performance and memory usage.

use std::path::PathBuf;

fn handle_path(path: &mut Option<PathBuf>) {
    match path {
        Some(path) => {
            let check = path.pop();
            if check {
                do_loop(Some(*path));
            }
        }
        None => {}
    }
}

fn do_loop(path: &mut Option<PathBuf>) {
    for i in 0..2 {
        handle_path(path);
    }
}
fn main() {
    do_loop(&mut Some("foo/bar".into()));
    do_loop(&mut None);
}

Solution

  • While destructuring the option, you reused the same variable name (path), thus your parameter (still holding the modified path) is not useable anymore (this is called shadowing a variable). Choosing another name in the pattern matching allows you to pass the same parameter to the recursive call.

    fn handle_path(path: &mut Option<PathBuf>) {
        match path {
            Some(inner_path) => {
                let check = inner_path.pop();
                if check {
                    do_loop(path);
                }
            }
            None => {}
        }
    }