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

戏子无情 提交于 2020-01-15 07:48:28

问题


Even after reading the chapters about reference ownership and borrowing, I cannot understand some things in the following code, effectively stopping me from calling more than one method 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()
    );
}

Compiling this code leads to:

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. 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?
  2. I thought app would still have ownership of the object, yet the compiler has a different opinion.

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


回答1:


Read the function signature for App::get_matches:

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

This takes self by value, also said as it consumes the value; you cannot call any methods on it afterwards. There's nothing to be done about this; presumably the author has good rationale for this.

Now review App::print_help:

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

It takes a reference (which happens to be mutable). You do not have to transfer ownership to call this method.


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?

You do not understand correctly, in multiple dimensions.

  1. get_matches consumes the value, it does not borrow anything.
  2. A value does not need to be mutable to be borrowed.
  3. When you do borrow something, the ownership doesn't "go" anywhere. The original owner continues to own it. That's why it's called borrowing.

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

You don't. The obvious workaround is to clone the original object, producing a second value. Then you can consume one value and still call methods on the second value.


Basically, it sounds like you are trying to do something that the library is discouraging you from doing. Perhaps you should re-evaluate your goals and/or review the intended usage of the library. For example, get_matches will automatically display the help text when the user requests it, so why should your code try to do so?

From the 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.



来源:https://stackoverflow.com/questions/40951538/method-call-on-clapapp-moving-ownership-more-than-once

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!