0Pricing
Learn Rust Coding · 课时

子命令

结构化 CLI

子命令 是 CoddyKit 上的免费 Learn Rust Coding 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Learn Rust Coding 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Learn Rust Coding 课程共包含 4 节课。

什么是子命令?

子命令让一个二进制程序提供多个操作,例如 git commit 和 git push。

  • 每个子命令都有自己的参数
  • 随着 CLI 的增长,这种结构也能扩展

clap 使用嵌套的 Command 值来表示这些子命令。

添加子命令

使用 .subcommand() 附加一个子命令。父命令会成为分发器。

use clap::Command;

fn main() {
    Command::new("todo")
        .subcommand(Command::new("add"))
        .subcommand(Command::new("list"))
        .get_matches();
}

匹配选中的子命令

解析后,subcommand() 会告诉您运行的是哪个子命令。根据其名称进行匹配即可分发处理。

use clap::Command;

fn main() {
    let m = Command::new("todo")
        .subcommand(Command::new("add"))
        .subcommand(Command::new("list"))
        .get_matches();
    match m.subcommand() {
        Some(("add", _)) => println!("adding"),
        Some(("list", _)) => println!("listing"),
        _ => println!("no subcommand"),
    }
}

子命令中的参数

子命令带有自己的参数。下面的 add 命令接收任务描述。

use clap::{Command, Arg};

fn main() {
    Command::new("todo")
        .subcommand(
            Command::new("add")
                .arg(Arg::new("task").required(true))
        )
        .get_matches();
}

读取子命令参数

元组的第二个元素是子命令的 ArgMatches。从中提取值的方式与顶层命令相同。

use clap::{Command, Arg};

fn main() {
    let m = Command::new("todo")
        .subcommand(Command::new("add").arg(Arg::new("task")))
        .get_matches();
    if let Some(("add", sub)) = m.subcommand() {
        let task = sub.get_one::<String>("task").unwrap();
        println!("add: {}", task);
    }
}

要求使用子命令

使用 subcommand_required(true),这样直接运行二进制程序时会打印帮助信息,而不是不执行任何操作。

use clap::Command;

fn main() {
    Command::new("todo")
        .subcommand_required(true)
        .arg_required_else_help(true)
        .subcommand(Command::new("list"))
        .get_matches();
}

使用纯 Rust 模拟分发

子命令 CLI 的核心是对字符串进行匹配。这个可运行示例复现了该分发逻辑。

fn main() {
    let cmd = "add";
    let task = "Buy milk";
    match cmd {
        "add" => println!("Added: {}", task),
        "list" => println!("Listing tasks"),
        other => println!("Unknown command: {}", other),
    }
}

嵌套子命令

子命令本身还可以包含子命令,例如 cargo build --release,也可以构建更深的树形结构。只需继续嵌套调用 .subcommand()。

use clap::Command;

fn main() {
    Command::new("app")
        .subcommand(
            Command::new("config")
                .subcommand(Command::new("get"))
                .subcommand(Command::new("set"))
        )
        .get_matches();
}

每个子命令的帮助

每个子命令都有自己的 --help 页面。添加 about 字符串来描述它。

use clap::Command;

fn main() {
    Command::new("todo")
        .subcommand(
            Command::new("add").about("Add a new task")
        )
        .get_matches();
}

别名

使用 visible_alias 为用户提供快捷方式。现在 ls 和 list 都可以使用。

use clap::Command;

fn main() {
    Command::new("todo")
        .subcommand(
            Command::new("list").visible_alias("ls")
        )
        .get_matches();
}

返回退出代码

完善的 CLI 会明确表示成功或失败。可以在子命令中使用 std::process::exit 返回非零代码,或者让 main 返回 Result。

fn main() {
    let success = true;
    if !success {
        std::process::exit(1);
    }
    println!("ok");
}

快速检查

测试您对​​子命令的理解。

总结

现在您可以使用子命令构建结构化的 CLI:

  • 使用 .subcommand() 添加子命令
  • 通过匹配 m.subcommand() 进行分发
  • 每个子命令都有自己的参数和帮助页面
  • 使用 subcommand_required 和别名让 CLI 更完善

下一步:derive API 会将结构体转换为参数解析器。

常见问题解答

「子命令」课时是免费的吗?

是的 — 「子命令」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Learn Rust Coding 课程的其余内容,请升级到 CoddyKit PRO。 Learn Rust Coding 课程共包含 4 节课。

「子命令」这节课中我会学到什么?

结构化 CLI 你通过在浏览器中直接运行的动手代码来练习 Learn Rust Coding,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Learn Rust Coding 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Learn Rust Coding 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「子命令」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Learn Rust Coding 课中编写并运行代码吗?

能。每节 Learn Rust Coding 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. clap 基础
  2. 子命令
  3. 派生 API
  4. 验证与帮助信息
← 返回 Learn Rust Coding