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

Jie*_*ong 6 ownership rust clap

即使在阅读了有关引用所有权和借用的章节之后,我仍然无法理解以下代码中的某些内容,这有效地阻止了我从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()
    );
}
Run Code Online (Sandbox Code Playgroud)

编译此代码会导致:

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()
    );
}
Run Code Online (Sandbox Code Playgroud)
  1. 如果我理解正确的话,app.get_matches()要求借用所有权,那么app一定是mut。一旦函数返回,所有权会去哪里?
  2. 我认为app仍然拥有该对象的所有权,但编译器有不同的意见。

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

She*_*ter 6

读取函数签名App::get_matches

fn get_matches(self) -> ArgMatches<'a>
Run Code Online (Sandbox Code Playgroud)

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

现在回顾App::print_help

fn print_help(&mut self) -> ClapResult<()>
Run Code Online (Sandbox Code Playgroud)

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


如果我理解正确的话,app.get_matches()要求借用所有权,因此应用程序必须是mut. 一旦函数返回,所有权会去哪里?

你在多个维度上理解不正确。

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

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

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


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

来自Clap 问题跟踪器

你有几个选择。您可以使用AppSettings::ArgRequiredElseHelp,也可以使用 来阻止移动的发生App::get_matches_from_safe_borrow

  • 回复:“想必作者对此有充分的理由”......我直接在 Clap 问题跟踪器上询问:https://github.com/kbknapp/clap-rs/issues/785 (2认同)