I want to pass list of directory names to function, like so:
use std::path::Path;
fn test(dirs: &Vec<Path>) {}
fn main() {
let dirs = vec![Path::new("/tmp"), Path::new("/var/tmp")];
test(dirs);
}
But it does not compile:
<anon>:3:5: 4:6 error: the trait bound `[u8]: std::marker::Sized` is not satisfied [E0277]
<anon>:3 fn test(dirs: &Vec<Path>) {
<anon>:4 }
<anon>:3:5: 4:6 help: see the detailed explanation for E0277
<anon>:3:5: 4:6 note: `[u8]` does not have a constant size known at compile-time
<anon>:3:5: 4:6 note: required because it appears within the type `std::sys::os_str::Slice`
<anon>:3:5: 4:6 note: required because it appears within the type `std::ffi::OsStr`
<anon>:3:5: 4:6 note: required because it appears within the type `std::path::Path`
<anon>:3:5: 4:6 note: required by `std::vec::Vec`
Looks like Path not Sized
?
How should I fix this, if I do not want to pass Vec<String>
to function?
Maybe PathBuf
? How to implement this in rusty way?
Indeed, Path
is an unsized type, just like str
. Pretty much the only sensible way to work with a Path
is to take a reference to it: &Path
(just like &str
). So your example would look like this:
use std::path::Path;
fn test(dirs: &[&Path]) {}
fn main() {
let dirs = vec![Path::new("/tmp"), Path::new("/var/tmp")];
test(&dirs);
}
Not that I also changed the &Vec<_>
to &[_]
. A reference to a Vec
is not more powerful than a slice (&[_]
), thus the idiomatic way is to pass slices instead of references to vectors.
The above solution is the correct way if you don't want to transfer ownership to the test
function. If you want to transfer ownership (including the string buffer actually saving the path data), you should use PathBuf
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With