代码之家  ›  专栏  ›  技术社区  ›  Alexis Purslane

变量生存时间不够长:与Option类型匹配

  •  5
  • Alexis Purslane  · 技术社区  · 9 年前

    我使用的是getopts,之前我从一个像这样的标志中获得了一个值:

    let file = matches.opt_str("f").unwrap();
    let file_path = Path::new(&file);
    

    但是,我希望通过使路径可选来更好地处理可能的错误。这是我的新代码:

    let file = matches.opt_str("f");
    let file_path = match file {
        Some(f) => Some(Path::new(&f)),
        None    => None
    }
    

    但是,当我试图编译这段代码时,我得到了错误 'f' does not live long enough 。我完全被难住了。

    这是我代码的MCVE:

    use std::path::Path;
    
    fn main() {
        let foo = Some("success".to_string());
        let string = match foo {
            Some(s) => Some(Path::new(&s)),
            None    => None
        };
    }
    
    error[E0597]: `s` does not live long enough
     --> src/main.rs:6:35
      |
    5 |     let string = match foo {
      |         ------ borrow later stored here
    6 |         Some(s) => Some(Path::new(&s)),
      |                                   ^^ - `s` dropped here while still borrowed
      |                                   |
      |                                   borrowed value does not live long enough
    
    1 回复  |  直到 2 年前
        1
  •  7
  •   Shepmaster Lukas Kalbertodt    2 年前

    问题的出现是因为你 取得所有权 的内容 Option 与绑定匹配 s (使用 按值绑定 ). 然而,由于没有使用 s 在匹配臂之后,它将被丢弃并导致无效引用,因此它被阻止。

    相反,你可以 引用绑定 :

    let string = match foo {
        Some(ref s) => Some(Path::new(s)),
        None        => None,
    };
    

    你也可以得到 Option<&T >来自 Option<T> 使用 as_ref :

    let string = match foo.as_ref() {
        Some(s) => Some(Path::new(s)),
        None    => None,
    };
    

    我可能会使用最后一个解决方案 map :

    let string = foo.as_ref().map(Path::new);
    

    在现代Rust中,您可以利用 符合人体工程学 并在 &Option<T> :

    let string = match &foo {
        Some(s) => Some(Path::new(s)),
        None    => None,
    };
    

    另请参见: