Reputation: 9224
I trying to get a list of mp3 from a directory.
let dir_paths = fs::read_dir(&Path::new("some_directory")).unwrap();
let paths = dir_paths.filter(|x| match x.unwrap().path().extension() {
None => true,
Some(ext) => ext == "mp3"
});
The Error Message
src/main.rs:27:48: 27:49 error: cannot move out of borrowed content
src/main.rs:27 let paths = dir_paths.filter(|ref x| match x.unwrap().path().extension() {
^
I tried replacing |x|
with |ref x|
but got the same error message. What is correct way of doing this
Upvotes: 2
Views: 242
Reputation: 432089
Let's take a look at the documentation for Result::unwrap
:
fn unwrap(self) -> T
Unwraps a result, yielding the content of an Ok.
Note how it takes self
? That means that the option will be consumed. However, your iterator is passing the closure a &Result<T, _>
. You can't take ownership of the Option
because it is borrowed.
The shortest fix is to get an Result<&T, _>
instead, using as_ref
:
use std::fs;
fn main() {
let dir_paths = fs::read_dir("/").unwrap();
let paths = dir_paths.filter(|x| match x.as_ref().unwrap().path().extension() {
None => true,
Some(ext) => ext == "mp3"
});
}
Although I might choose to write it as
use std::fs;
use std::ffi::OsStr;
fn main() {
let dir_paths = fs::read_dir("/").unwrap();
dir_paths
.filter_map(|x| x.ok())
.filter(|x| x.path().extension().and_then(OsStr::to_str) == Some("mp3"));
}
There's some less unwraps - we just ignore any failed DirEntry
s. That's up to your error handling strategy though.
Upvotes: 4