Rust 命令行参数解析指南

0x00 前言

通过 Rust 的 Governance 可以看到 Rust 的通过三种方式管理社区:

  • RFC process
  • Teams
  • Working Groups

在 Working Groups 中我发现竟然有一个叫 Command-line interfaces (CLI) working group 的工作组(简称 WG-CLI)。很明显,如果 Rust 对于 CLI 类的应用程序是非常重视的,从编译体积/执行效率/安全性 上都可以作为新生 CLI 类应用开发的首选语言。CLI 类应用主要的输入方式是命令行参数,本文主要讨论 Rust 中处理命令行参数的几种常规方法。

0x01 std::env::args()

Rust 为了适配更多的场景,很多机制都只提供一个极简的可任意扩展的接口,例如支持异步机制时只提供了 Future 这个无法独立运行的概念,而需要引入自己维护的一个第三方 crate 才能使用 async/await 语义。在命令行处理上也是如此,通过 std 只能使用 env::args() 来获取命令行参数,剩下的流程都靠开发者自己实现。

下面是使用 std::env::args() 打印命令行参数的一个示例:

rust 复制代码
use std::{env, process};

fn print_args(args: impl Iterator<Item = String>) -> Result<(), &'static str> {
    for argument in args {
        println!("{}", argument);
    }
    Ok(())
}

fn main() {
    print_args(env::args()).unwrap_or_else(|err| {
        eprintln!("Problem parsing arguments: {}", err);
        process::exit(1);
    });
}

显然对于简单的命令行参数,这种方式可以在不引入第三方 crate 的情况下实现功能,但是对于一些需要处理复杂输入参数的场景确实比较吃力,剩下的交给 Rust 生态,接下来我们通过一些比较流行的命令行处理 crate 展开学习。

0x02 3rd-party

有一个非常有意思的 Repo ---- argparse-rosetta-rs 对比了几种常见命令行参数处理 crate。

Name Style Notes
argh derive
bpaf Combinatoric or derive
clap_lex Imperative No help generation
clap Builder or derive Color, suggested fixes, completions
gumdrop derive
lexopt Imperative No help generation
pico-args Imperative No help generation
xflags proc-macro

按照调用风格可以分为两类:

  • 命令式 (Imperative)
  • 声明式 (Declarative)

命令式方式通常比较直观,将参数解析结构化成支持 iterate and match 的形式。声明式的方式主要有两种,一种是通过链式 Builder 方式声明一个 Command,然后去 match 输入的命令行参数;另一种是通过 Rust 的 derive 机制声明结构体后进行 parse。具体使用方式可以参考上表中每个 crate 文档中的示例。

0x03 结论

Rust 命令行参数 crate 中最流行的 clap 的主要维护者 Ed Page 同时也是 WG-CLI 的 team leader,这种生态模式让 Rust 的生态更加多样性的同时也更具有实践价值,我们从命令行参数处理这一个点来多层次观察 Rust 的语言发展策略,生态构建方式,可以看出,Rust 吸取了前辈的一些成功和失败经验,正在成为一个生命力强劲的编程语言。

Reference

相关推荐
冬奇Lab16 小时前
一天一个开源项目(第42篇):OpenFang - 用 Rust 构建的 Agent 操作系统,16 层安全与 7 个自主 Hands
人工智能·rust·开源
量子位20 小时前
Transformer论文作者重造龙虾,Rust搓出钢铁版,告别OpenClaw裸奔漏洞
rust·openai·ai编程
哈里谢顿1 天前
Rust 语言入门博客
rust
DongLi013 天前
rustlings 学习笔记 -- exercises/06_move_semantics
rust
ssshooter3 天前
Tauri 踩坑 appLink 修改后闪退
前端·ios·rust
布列瑟农的星空3 天前
前端都能看懂的rust入门教程(二)——函数和闭包
前端·后端·rust
蚂蚁背大象4 天前
Rust 所有权系统是为了解决什么问题
后端·rust
布列瑟农的星空4 天前
前端都能看懂的rust入门教程(五)—— 所有权
rust
Java水解5 天前
Rust嵌入式开发实战——从ARM裸机编程到RTOS应用
后端·rust
Pomelo_刘金5 天前
Rust:所有权系统
rust