(values_of) cannot return value referencing local variable matches
#2107
-
From this example: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=4ff6b06028b40df40bf01cf1d2809135, I want to use the matched arguments use clap::{App, Arg, SubCommand}; // 2.33.1
#[derive(Debug)]
enum Action<'a> {
GET(Option<&'a str>),
}
fn main() {
let a = options().unwrap();
println!("{:#?}", a);
}
fn options<'a>() -> Result<Action<'a>, ()> {
let home_dir = std::path::PathBuf::from("/tmp");
let default_config = format!("{}/.s3m/config.yml", home_dir.display());
let matches = App::new("test")
.arg(
Arg::with_name("config")
.default_value(&default_config)
.required(true)
.value_name("config.yml"),
)
.subcommand(
SubCommand::with_name("ls")
.about("list objects")
.arg(Arg::with_name("arguments").required(true).min_values(1)),
)
.get_matches();
let args: Vec<&str> = if let Some(ls) = matches.subcommand_matches("ls").to_owned() {
ls.values_of("arguments").unwrap_or_default().collect()
} else {
matches.values_of("arguments").unwrap_or_default().collect()
};
let dir = if args.is_empty() { None } else { Some(args[0]) };
// this works with Some("foo")
// let dir = if args.is_empty() { None } else { Some("foo") };
Ok(Action::GET(dir))
} How could I create the vector use so that I could use the collected values when returning? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 5 replies
-
Short answer: Long answer: I think you have just yet to comprehend rust borrowing rules and lifetimes. See the book: https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#dangling-references |
Beta Was this translation helpful? Give feedback.
-
Hi @CreepySkeleton thanks for the link, I still trying to understand how to return a let args: Vec<String> = if let Some(ls) = matches.subcommand_matches("ls") {
if let Some(a) = ls.values_of("arguments") {
a.into_iter().collect()
}
} else {
if let Some(a) = matches.values_of("arguments") {
a.into_iter().collect()
}
}; I get errors like:
or
Any hint about how could I use |
Beta Was this translation helpful? Give feedback.
Short answer:
matches
is a local variable,value_of
borrows from it and therefore the returned&str
reference must not outlivematches
, but you're trying to return the ref while matches will be dropped when execution reaches the end of the function, so the ref will become invalid. The solution is to returnVec<String>
- no references, no problems (and a slight perf penalty you won't even notice).Long answer: I think you have just yet to comprehend rust borrowing rules and lifetimes. See the book: https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#dangling-references