我有一个像这样的结构,带有一些解析的参数:
struct Args {
out: Option<String>,
version: bool,
help: bool,
files: Vec<String>,
}
我想递归地解析一个列表,每次需要修改它时返回一个新的修改过的Args
结构:
fn parse(parsed: &Args, start: usize, args: Vec<String>) -> Args {
if start >= args.len() {
return parsed.clone();
}
if args[start] == "--version" {
return parse(&Args { version: true, ..parsed.clone() }, start + 1, args);
}
if args[start] == "--help" {
return parse(&Args { help: true, ..parsed.clone() }, start + 1, args);
}
return Args { files: args[start..args.len()].to_vec(), ..parsed.clone() };
}
我使用这样的功能:
fn main() {
let args = std::env::args().collect::<Vec<String>>();
let parsed = parse(&Args::default(), 1, args);
}
此代码有效,但我想输入:
return parse(&Args { version: true, ..parsed }, start + 1, args);
而不是:
return parse(&Args { version: true, ..parsed.clone() }, start + 1, args);
以避免克隆过程中过多的数据复制。当我删除.clone()
时,它表示预期Args
类型,但它改为&Args
。
当我使用*parsed
编译器解除引用时说&#34;无法摆脱借来的内容&#34;
答案 0 :(得分:2)
当T
类型为Clone
时,在clone()
上调用&T
也会返回T
,因为没有任何意义复制指针。事实上,如果 克隆了基础数据,然后返回对它的引用,那么你就会遇到麻烦,因为T
会被删除,而指针会悬空。< / p>
要将&T
变为T
,您可以使用*
运算符取消引用它。但是,这会给你带来问题,因为parsed
函数借用了parse
,这意味着它必须在完成时将其归还。如果您取消引用它并移动值,那么您将从借用的上下文中移出。