使用Path和PathBuf局部变量了解生命周期

时间:2017-11-03 01:04:42

标签: rust

我创建了一个具有&Path和两个&str的结构。我尝试在结构上定义一个方法,给定一个Path - 就像表示相对文件路径一样,将它连接到根,规范化它,验证结果路径是否包含在根目录中,并返回相对路径和绝对路径的元组,或者返回错误(使用Result):

use std::path::Path;
use std::path::PathBuf;

mod error {
    use std::error;
    use std::fmt;
    use std::path;

    #[derive(Debug)]
    pub enum MediaLibraryError<'a> {
        NonAbsPath(&'a path::Path),
        NonRelPath(&'a path::Path),
    }

    impl<'a> error::Error for MediaLibraryError<'a> {
        // This is meant to be a static description of the error, without any computation!
        fn description(&self) -> &str {
            match self {
                &MediaLibraryError::NonAbsPath(_) => "File path was was expected to be absolute",
                &MediaLibraryError::NonRelPath(_) => "File path was was expected to be relative",
            }
        }
    }

    impl<'a> fmt::Display for MediaLibraryError<'a> {
        // This is the place to put formatted/computed error messages!
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            match self {
                &MediaLibraryError::NonAbsPath(x) => {
                    write!(f, r##"Path "{:?}" is not absolute"##, x)
                }
                &MediaLibraryError::NonRelPath(x) => {
                    write!(f, r##"Path "{:?}" is not relative"##, x)
                }
            }
        }
    }
}

use error::MediaLibraryError;

struct MediaLibrary<'a> {
    root_dir: &'a Path,
    item_meta_fn: &'a str,
    self_meta_fn: &'a str,
}

impl<'a> MediaLibrary<'a> {
    fn co_norm<P: AsRef<Path>>(
        &self,
        rel_sub_path: P,
    ) -> Result<(PathBuf, PathBuf), MediaLibraryError> {
        let rel_sub_path = rel_sub_path.as_ref().to_path_buf();

        if !rel_sub_path.is_relative() {
            return Err(MediaLibraryError::NonRelPath(&rel_sub_path));
        }

        let abs_sub_path = self.root_dir.join(&rel_sub_path);

        // Canonicalize.
        // Check that created absolute path is a child of root or root itself.

        Ok((rel_sub_path.to_path_buf(), abs_sub_path))
    }
}

fn main() {}

但是,在尝试编译时,我收到此错误:

error[E0597]: `rel_sub_path` does not live long enough
  --> src/main.rs:56:55
   |
56 |             return Err(MediaLibraryError::NonRelPath(&rel_sub_path));
   |                                                       ^^^^^^^^^^^^ does not live long enough
...
65 |     }
   |     - borrowed value only lives until here
   |
note: borrowed value must be valid for the anonymous lifetime #1 defined on the method body at 49:5...
  --> src/main.rs:49:5
   |
49 | /     fn co_norm<P: AsRef<Path>>(
50 | |         &self,
51 | |         rel_sub_path: P,
52 | |     ) -> Result<(PathBuf, PathBuf), MediaLibraryError> {
...  |
64 | |         Ok((rel_sub_path.to_path_buf(), abs_sub_path))
65 | |     }
   | |_____^

一个常见的初学者错误,我确定,但对于我的生活,我似乎无法弄清楚要做什么。我使用PathBuf / Path尝试使用as_ref()而不是to_owned()来尝试搞乱生命。然而,一切都是徒劳的。我觉得这里有一个很好的教训,但是我很难过。

PS:我正在使用文档中的P: AsRef<Path>,我的理解是它允许传递&strPathPathBuf等方法?

0 个答案:

没有答案