Push vector in a loop


#1

Hello Rustacean,

I’ve got a little problem with vector, loop and variable lifetime.

fn main() {
    let mut list = Vec::new();
    for file in WalkDir::new(".") {
        let file = file.unwrap();
        list.push(file.path());
    }
}

My variable stop at the first curly bracket but it need to end at the second.

In my mind, I send the content of the variable file in the list and that’s it.

How can I fix it ?
Thanks


#2

Hi there,

fn main() {
    let mut list = Vec::new();
    for file in WalkDir::new(".") {
        let file = file.unwrap();
        list.push(file.path().to_owned());
   }
}

This is a first solution, maybe not the best. :slight_smile:

https://doc.rust-lang.org/nightly/std/path/struct.Path.html // Path struct implements ToOwned traits :slight_smile:

https://mobiarch.wordpress.com/2015/06/29/understanding-lifetime-in-rust-part-i/ // interesting read and maybe hint to find a better way ?

Cya’


#3

As Mosicus writes, you can avoid this by calling to_owned.

You can also avoid pushing onto the vector manually:

extern crate walkdir;

use walkdir::*;

fn main() {
    let list: Vec<_> = WalkDir::new(".")
                        .into_iter()
                        .filter_map(|f| f.ok()) // filter out errors (silently!)
                        .map(|f| f.path().to_owned()) // take the path and take ownership
                        .collect(); // collect into whatever list is
}

Vectors can be created from any previous iteration efficiently. Detailed explanations on the chain:

  • Walkdir#into_iter creates an Iterator from the WalkDir structure
  • filter_map gives you every element and expects an Option returned. It filters out everything that is None. Result::ok() turns a result into an Option by discarding all errors and making them None.
  • map applies an operation to every element and gives you the Result
  • finally, collect() collects all elements into a some collection. This is why we have to annotate list with Vec, because Rust needs to know which type of collection you want. The underscore in Vec<_> tells the compiler to infer the type inside the collection.

#4

@Morsicus Thanks :slight_smile: I really need to understand lifetime and owner thing in rust.

@Skade Wow, I didn’t expect we can use vector like this, much readable and easier. Thanks.
I need to read the doc for more detail but thanks :slight_smile:


#5

You can read about the collect function here. It lets you create any collection from this list.