跳到主要内容

命令行解析

问题

Rust 如何构建命令行工具?

答案

clap 是 Rust 最流行的命令行解析库,支持 derive 宏声明式定义。

derive API(推荐)

use clap::{Parser, Subcommand, ValueEnum};

/// 一个简单的 CLI 工具
#[derive(Parser)]
#[command(name = "mytool", version, about = "演示 CLI 工具")]
struct Cli {
/// 输入文件路径
#[arg(short, long)]
input: String,

/// 输出格式
#[arg(short, long, default_value = "json", value_enum)]
format: OutputFormat,

/// 详细输出
#[arg(short, long, action = clap::ArgAction::Count)]
verbose: u8,

#[command(subcommand)]
command: Option<Commands>,
}

#[derive(ValueEnum, Clone)]
enum OutputFormat {
Json,
Csv,
Table,
}

#[derive(Subcommand)]
enum Commands {
/// 初始化项目
Init {
#[arg(short, long)]
name: String,
},
/// 运行任务
Run {
/// 任务名
task: String,
},
}

fn main() {
let cli = Cli::parse();

match cli.verbose {
0 => println!("正常模式"),
1 => println!("详细模式"),
_ => println!("调试模式"),
}

if let Some(cmd) = cli.command {
match cmd {
Commands::Init { name } => println!("初始化: {}", name),
Commands::Run { task } => println!("运行: {}", task),
}
}
}

使用方式:

mytool --input data.txt --format csv -vv init --name myproject

常用特性

特性属性说明
必选参数默认input: String
可选参数Option<T>input: Option<String>
默认值default_value#[arg(default_value = "8080")]
环境变量env#[arg(env = "PORT")]
布尔开关action = SetTrue--verbose
计数action = Count-vvv → 3
枚举值value_enum自动生成可选值列表

常见面试问题

Q1: clap 的 derive API 和 builder API 有什么区别?

答案

  • derive API:通过 #[derive(Parser)] 声明式定义,代码简洁,编译时检查,推荐大多数场景
  • builder APICommand::new().arg(...) 编程式构建,运行时动态构造参数,适合需要动态生成参数的场景

两者功能等价,derive API 是 builder API 的语法糖。

相关链接