多次调用 clap::App 移动所有权的方法

Method call on clap::App moving ownership more than once

即使阅读了有关引用所有权和借用的章节,我还是无法理解以下代码中的某些内容,这实际上阻止了我从 clap::App!

调用多个方法
extern crate clap;

use clap::App;

fn main() {
    let mut app =
        App::new("name me").args_from_usage("<input_file>          'Sets the input file to use'");
    let matches = app.get_matches();
    app.print_help();
    println!(
        "Using input file: {}",
        matches.value_of("input_file").unwrap()
    );
}

编译此代码导致:

error[E0382]: use of moved value: `app`
 --> src/main.rs:9:5
  |
8 |     let matches = app.get_matches();
  |                   --- value moved here
9 |     app.print_help();
  |     ^^^ value used here after move
  |
  = note: move occurs because `app` has type `clap::App<'_, '_>`, which does not implement the `Copy` trait
  1. 如果我没理解错的话,app.get_matches()要求借用所有权,所以app一定是mut。函数 returns?
  2. 后所有权去哪儿了
  3. 我认为 app 仍然拥有该对象的所有权,但编译器有不同的意见。

我怎样才能得到匹配项,并且仍然有效地调用另一个方法,例如 app 上的 print_help 呢?

阅读 function signature for App::get_matches:

fn get_matches(self) -> ArgMatches<'a>

这取self的值,也可以说是消耗的值;您之后不能调用它的任何方法。对此无能为力;想必作者对此有充分的理由。

现在回顾App::print_help:

fn print_help(&mut self) -> ClapResult<()>

它需要一个引用(恰好是可变的)。您无需转移所有权即可调用此方法。


If I understand correctly, app.get_matches() asks to borrow the ownership, thus app must be mut. Where does the ownership go once the function returns?

你没有理解正确,多维度的。

  1. get_matches消耗价值,它不借任何东西。
  2. 借用的值不需要可变。
  3. 当你借东西的时候,所有权并不在任何地方"go"。原主人继续拥有它。这就是为什么它被称为 借用.

How can I get the matches, and effectively still call another method, such as print_help on app then?

你不知道。显而易见的解决方法是克隆原始对象,产生第二个值。然后你可以使用一个值并仍然调用第二个值的方法。


基本上,听起来您正在尝试做图书馆不鼓励您做的事情。也许您应该重新评估您的目标 and/or 查看库的预期用途。例如,get_matches 会在用户请求时自动显示帮助文本,那么您的代码为什么要尝试这样做?

来自Clap issue tracker:

You have a few options. You can either use AppSettings::ArgRequiredElseHelp or you can keep the move from happening by using App::get_matches_from_safe_borrow.