Rust中的生命周期,所有权和借用;理解"简单"条件作品

时间:2018-03-27 13:26:11

标签: rust lifetime borrow-checker

作为Rust的新手,我很难理解这些最重要的功能。我已多次阅读TRPL(1和2)的相关章节,但我仍然无法编译代码。作为一个例子,我已经提取并简化了一个更大项目的一部分。

此示例程序从命令行参数构建字符串列表(我使用过Vec),或者,如果给出了-c参数,则从剪贴板构建。

extern crate clipboard;
use clipboard::{ClipboardContext, ClipboardProvider};

extern crate clap;
use clap::{App, Arg, ArgMatches};

#[allow(unused)] // Reduce noise in compiler output
fn main() {
    let cmdl: ArgMatches = App::new("mwe")
        .arg(
            Arg::with_name("clipboard")
                .short("c")
                .conflicts_with("list")
                .takes_value(false),
        )
        .arg(
            Arg::with_name("list")
                .takes_value(true)
                .required_unless("clipboard")
                .multiple(true),
        )
        .get_matches();
    println!("{:?}", cmdl);

    let vlist: Vec<&str> = Vec::new();
    if cmdl.is_present("clipboard") {
        let mut ctx: ClipboardContext = ClipboardProvider::new().unwrap();
        let vlist = ctx.get_contents()
            .unwrap()
            .split_whitespace()
            .collect::<Vec<_>>();
    } else {
        let vlist = cmdl.values_of("list").unwrap().collect::<Vec<_>>();
    };
    println!("{:?}", vlist);
}

编译时,这是输出:

error[E0597]: borrowed value does not live long enough
  --> src/main.rs:28:25
   |
28 |               let vlist = ctx.get_contents()
   |  _________________________^
29 | |                 .unwrap()
   | |_________________________^ temporary value does not live long enough
30 |                   .split_whitespace()
31 |                   .collect::<Vec<_>>();
   |                                       - temporary value dropped here while still borrowed
32 |           } else {
   |           - temporary value needs to live until here
   |
   = note: consider using a `let` binding to increase its lifetime

现在,我(至少)有两个问题:

  1. 我只是不明白为什么我写的是错误的。可能我只是一个慢学习者,或者,也许,为了感知借阅和生命周期的某些方面,人们必须对正在使用的库有更深入的理解。请解释一下这里发生了什么?
  2. 我不知道解决这个问题的最好和/或最有效的方法;请指导我。
  3. 作为一个脚注,这些&#34;没有更多垃圾收集&#34;功能是吸引我Rust的东西之一。但我偶尔也不能思考TRPL中的例子需要更简单,而且这个领域的学习曲线看起来更像是悬崖。所有的帮助和照明都非常赞赏。

    问题的持续演变

    关注https://stackoverflow.com/a/37265024/9634 this answer to “borrowed value does not live long enough” seems to blame the wrong thing(让我更好地了解了库内部),我修改了我的代码,替换

        let vlist = ctx.get_contents()
            .unwrap()
            .split_whitespace()
            .collect::<Vec<_>>();
    

    通过

    for item in ctx.get_contents().unwrap().split_whitespace() {
        vlist.push(&item.to_string()) ;
    } 
    

    错误现在有点动摇了:

    error[E0597]: borrowed value does not live long enough
      --> src\main.rs:24:25
       |
    24 |             vlist.push(&item.to_string()) ;
       |                         ^^^^^^^^^^^^^^^^  - temporary value dropped here while still borrowed
       |                         |
       |                         temporary value does not live long enough
    ...
    32 | }
       | - temporary value needs to live until here
       |
       = note: consider using a `let` binding to increase its lifetime
    

    我非常希望遵循&#34的建议;使用let绑定来增加其生命周期&#34; (正如评论中所强调的那样),但我不知道这会是什么样子。请帮忙。

0 个答案:

没有答案