使用Clap如何指定一个布尔类型的命令行标志?

28

我想要添加一个命令行标志。这是一个标志,所以它不需要参数,它要么存在要么不存在。我还需要知道如何读取该标志,它可能是TRUE或FALSE。

以下是定义该标志的代码:

.arg(
    Arg::with_name("metal")
        .long("metal-micky")
        .required(false)
        .help("I want metal micky"),
)

我正在尝试像这样读取值:

let z = matches.value_of("metal");

然而,当我打印它时,结果是None

Translated: However, when I print it, the result is None.
println!("FLAG: {:?}", z);

即使我在命令行中指定了标志,它仍然是None

4个回答

25

不确定这是否是“批准”的方法,但我使用 Args::takes_value:

.arg(
    Arg::with_name("metal")
        .long("metal-micky")
        .required(false)
        .takes_value(false)
        .help("I want metal micky"),
)

检查标志是否已传递,使用matches.is_present("metal")方法。


在当前的 Clap 稳定版本中,这个答案已经过时了。请查看 ciresh 的答案。简而言之:将 takes_value(false) 替换为 num_args(0) - Scolopendre

22

你可以使用 action 属性来实现这个功能。如果你的字段是一个 bool 类型,那么默认情况下选择的操作是 ArgAction::SetTrue

这非常好,因为当调用参数时不需要设置值。当运行程序时,默认将该值设置为 true,如果未使用则设置为 false。

use clap::Parser;

/// This is a simple program
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct Args {
   /// It just works!
   #[clap(long, short, action)]
   it_just_works: bool,
}

fn main() {
   let args = Args::parse();

    println!("It just works {}!", args.it_just_works)
}

如果要更改默认行为,可以这样做:

#[clap(long, short, action=ArgAction::SetFalse)]

文档


12

目前接受的答案有点过时了,您不再需要在指定 takes_value(false) 时指定 required(false)。所以,您需要的是:

.arg(
    Arg::with_name("metal")
        .long("metal-micky")
        .takes_value(false)
        .help("I want metal mickey")

并使用matches.is_present("metal")检查其是否存在。


10
构建器模式的答案已经过时。在3.0中,with_name()已被替换为new(),而takes_value()已在4.0中被替换为num_args()。此外,在3.2中,is_present()已被替换为contains_id()。新版本应该是:
.arg(
     Arg::new("metal")
        .long("metal-micky")
        .required(false)
        .num_args(0)
        .help("I want metal micky"),
)

使用contains_id()检查是否已传递标志。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接