如何编写一个返回Vec<Path>的函数?

8
我正在阅读文档,尝试编写一些基本的文件I/O代码来帮助我学习Rust。
以下代码无法编译:
use std::fs;
use std::io;
use std::path::Path;

pub fn read_filenames_from_dir<P>(path: P) -> Result<Vec<Path>, io::Error>
where
    P: AsRef<Path>,
{
    let paths = try!(fs::read_dir(path));
    Ok(paths.unwrap())
}

出现编译错误:

error[E0277]: the trait bound `[u8]: std::marker::Sized` is not satisfied in `std::path::Path`
  --> src/main.rs:5:1
   |
5  | / pub fn read_filenames_from_dir<P>(path: P) -> Result<Vec<Path>, io::Error>
6  | | where
7  | |     P: AsRef<Path>,
8  | | {
9  | |     let paths = try!(fs::read_dir(path));
10 | |     Ok(paths.unwrap())
11 | | }
   | |_^ `[u8]` does not have a constant size known at compile-time
   |
   = help: within `std::path::Path`, the trait `std::marker::Sized` is not implemented for `[u8]`
   = note: required because it appears within the type `std::path::Path`
   = note: required by `std::vec::Vec`

我应该如何编写此函数,以返回传入的Path中包含的Path集合?

1个回答

11

不需要这样做。 Path 是一个没有大小的类型,只能通过间接引用(例如&PathBox<Path>)使用。在这个意义上,它类似于类型str[u8] - 都不能直接使用,只能间接使用。

你可能想要的是一个PathBuf,它表示拥有路径。 它相当于String对于&strVec<u8>对于&[u8]

更改返回类型后,您必须正确地将迭代器的结果映射到所需的类型:

use std::{
    fs, io,
    path::{Path, PathBuf},
};

pub fn read_filenames_from_dir<P>(path: P) -> Result<Vec<PathBuf>, io::Error>
where
    P: AsRef<Path>,
{
    fs::read_dir(path)?
        .into_iter()
        .map(|x| x.map(|entry| entry.path()))
        .collect()
}

fn main() {
    println!("{:?}", read_filenames_from_dir("/etc"));
}

另请参阅:


1
“Path”到底是什么?通过查看源代码,我发现“Path”包含“OsStr”,而“OsStr”又包含了一个叫做“sys::os_str::Slice”的东西,但我找不到它的实际定义。我猜测它基本上是对“[u8]”进行了几层抽象? - Linear
2
@Jsor 基本上是在 [u8] 上加了几层抽象 - 是的,在类Unix平台上。Windows则不同。这种抽象泄漏在OP的错误消息中:“core::marker::Sized未为类型 [u8] 实现”。* - Shepmaster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接