4

即使在阅读了有关引用所有权和借用的章节之后,我仍然无法理解以下代码中的某些内容,从而有效地阻止了我调用多个方法 from 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。函数返回后所有权去哪了?
  2. 我认为app仍然拥有该对象的所有权,但编译器有不同的意见。

我怎样才能获得匹配项,并且仍然有效地调用另一种方法,例如print_helpon appthen?

4

1 回答 1

5

阅读函数签名App::get_matches

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

self按价值取值,也称为消耗价值;之后您不能在其上调用任何方法。对此没有什么可做的。想必作者对此有充分的理由。

现在回顾App::print_help

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

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


如果我理解正确,app.get_matches()要求借用所有权,因此 app 必须是mut. 函数返回后所有权去哪了?

您在多个维度上没有正确理解。

  1. get_matches消耗价值,它不借任何东西。
  2. 借用值不需要是可变的。
  3. 当您确实借了东西时,所有权不会“消失”到任何地方。原所有者继续拥有它。这就是为什么它被称为借贷

我怎样才能获得匹配项,并且仍然有效地调用另一种方法,例如print_help在应用程序上呢?

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


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

来自Clap 问题跟踪器

你有几个选择。您可以使用AppSettings::ArgRequiredElseHelp,也可以使用App::get_matches_from_safe_borrow.

于 2016-12-03T19:30:37.940 回答