As a Rust newbie, I'm having a really hard time understanding what appear to be these most significant features. I have read the relevant sections TRPL (1 and 2) multiple times, and yet I still can't get my code to compile. As an example, I've extracted and simplified part of a bigger project.
This example program builds a list of strings (I've used Vec), either from the command line arguments, or, if the -c parameter is given, from the clipboard.
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);
}
On compiling, this is the output:
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
Now, I have (at least) two problems:
- I just don't understand why what I've written is in error. It may be that I'm just a slow learner, or, maybe, that to perceive some aspects of borrowing and lifetimes one has to have a more intimate understanding of the libraries one is using. Please explain what's going on here?
- I have no idea of the best and/or most efficient way to fix this; please guide me.
As a footnote, these "no-more-garbage-collection" features are one of the things that attract me to Rust. But I can't help thinking, occasionally, that the examples in TRPL need to be simpler, and that the learning curve in this area looks more like a precipice. All help and illumination greatly appreciated.
Ongoing evolution of the problem
Following https://stackoverflow.com/a/37265024/9634 this answer to “borrowed value does not live long enough” seems to blame the wrong thing (which gave me a better understanding of the library internals), I amended my code, replacing
let vlist = ctx.get_contents()
.unwrap()
.split_whitespace()
.collect::<Vec<_>>();
by
for item in ctx.get_contents().unwrap().split_whitespace() {
vlist.push(&item.to_string()) ;
}
The error has now moved a little:
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
I'd like very much to follow the recommendation of "using a let binding to increase its lifetime" (as reinforced in the comments), but I haven't a clue what this would look like. Please help.