如何用Clap 4的derive API为Vec<String>参数设置默认值
Clap 4 Derive API 迁移:为多值参数设置默认值
问题场景
原Clap 2代码通过链式调用定义了一个支持多输入文件的参数,默认值为-(表示标准输入):
.arg( Arg::with_name("files") .value_name("FILE") .help("Input file(s)") .multiple(true) .default_value("-"), )
生成的命令行提示为:
USAGE: catr [FLAGS] [FILE]... FLAGS: -h, --help Prints help information
改用Clap 4的Derive API编写的Config结构体编译报错:
pub struct Config { /// The input files #[arg(default_value_t= vec!["-".to_string()])] files: Vec<String>, }
错误信息:
error[E0277]: `Vec<std::string::String>` doesn't implement `std::fmt::Display` --> src/lib.rs:10:11 | 10 | #[arg(default_value_t=vec!["-".to_string()])] | ^^^^^^^^^^^^^^^ `Vec<std::string::String>` cannot be formatted with the default formatter | = help: the trait `std::fmt::Display` is not implemented for `Vec<std::string::String>` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: required for `Vec<std::string::String>` to implement `ToString`
问题原因
default_value_t要求目标类型同时实现Display和FromStr trait,而Vec<String>并未实现Display,因此触发编译错误。而Clap 2中的default_value("-")是为多值参数指定单个默认元素,Clap会自动将其包装为集合类型。
解决方案
针对Clap 4 Derive API,有两种简洁的实现方式,都能和原Clap 2代码功能完全一致:
方式1:使用default_values属性
直接传入字符串切片数组作为默认值,Clap会自动完成类型转换,且无需额外指定多值特性(字段为Vec<String>时,Clap默认支持多参数输入):
pub struct Config { /// The input files #[arg(default_values = ["-"])] files: Vec<String>, }
方式2:使用default_value属性
因为字段是Vec<String>,Clap会自动将单个默认值包装为集合,效果和原Clap 2代码完全一致:
pub struct Config { /// The input files #[arg(default_value = "-")] files: Vec<String>, }
两种方式编译后生成的命令行提示都会和原Clap 2版本一致,且默认行为完全相同:未传入文件参数时,默认使用标准输入(-)。
内容的提问来源于stack exchange,提问作者DavidS
相关产品推荐
相关产品推荐

