How do I check the second element of the command l

2019-03-06 16:55发布

问题:

I need to check the second element to determine which action I'm doing to the rest of the arguments.

This loops through the command line arguments and skips the first one because it's always the program name. It also skips the second one because it's the operation I'm performing on the list:

for arg in std::env::args().skip(2)

I am doing the following which is redundant:

let check: Vec<String> = env::args().collect();

if check[1] == 'sort'{
    for arg in std::env::args().skip(2){
       //sort
    }
}

Is there a better way to do this?

回答1:

You can use nth():

let second_arg = env::args().nth(1).expect("no second arg");

which returns an Option<String>.

It is semantically equivalent to call skip(1) followed by next().

To go further, you can use pattern matching:

let mut args = env::args();
match args.nth(1).as_ref().map(|s| s.as_str()) {
    // args has been consumed so it will iterate over the next elements
    Some("sort") => for arg in args {
        println!("arg: {}", arg);
    },
    _ => {},
}

It is necessary to convert the argument from String to &str in order to be able to use Some("sort") as-is.

Alternatively, you might want to use a command line parsing package such as clap.



回答2:

In case you need to check the argument for a flag that may or may not be present, you may be able to use peekable:

use std::env;

fn main() {
    let mut args = env::args()
        .skip(1) // skip program name
        .peekable(); // allow looking forward one

    match args.peek().map(|x| x.as_ref()) {
        Some("--option1") => {
            args.next(); // Skip the flag
            println!("handle option 1");
        }
        Some("--option2") => {
            args.next(); // Skip the flag
            println!("handle option 2");
        }
        _ => {
            println!("handle no option");
        }
    }
}

Realistically, you should use a command line parsing package.



标签: rust