Rust 寫一個簡易 CLI 小工具

Mistreo發表於2024-07-13

關於學習了 Rust 一些基礎語法,想寫一個 demo 來鞏固一下基礎的語法知識,想到了可以寫一個 CLI 小工具。

大致思路

  1. cli 工具如執行 cli --help 可以列印出命令、引數幫助。
  2. cli 工具的引數可能不止一個 如 cli --hi NAME,列印的結果應該是 hi 你的名字

這就是一個簡單的 cli 工具的實現,我們會且僅用到標準庫,如果覺得功能不夠,可以自行新增,如 執行一個命令 可以往 Windows 的 HOST 新增內容,就需要用到 Rust 的 I/O。

開始實現

  1. 導包

首先我們匯入標準庫,我們會用到 std::env 下的 Args 結構體,它是 程序引數的迭代器,為每個引數產生 String 值。

use std::env;

fn main() {

}
  1. 定義 Help 內容
let help: &str = r#"
  cli 
      --help 幫助,檢視所有引數。
      --version 檢視版本。
      --hi NAME 向你打招呼。
"#

// 這裡我們使用 r#""# 不僅方便更鞏固 Rust 字串相關的知識點。
  1. 程式引數迭代器的使用
let args: Vec<String> = env::args().collect();

此處我們宣告一個名為 agrs ,值為String型別的向量,因為迭代器返回的是一串 String 型別的內容。

.collect() 方法就是去收集這些引數。

  1. 開始匹配引數
for arg: &String in args.iter() {
  match arg.as_str() {
    "--help" => {
      println!("{}", help);
      return;
    },
    "--version" => {
      println!("當前 cli 版本:{}", env!("CARGO_PKG_VERSION"));
      return;
    },
    _ => {
      //
    }
  }
}

println!("未能識別的引數!可以輸入 `cli --help` 獲取幫助。")

我們來逐一分析一下,

  • for arg: &String in args.iter() ,定義一個 for 迴圈。
  • match arg.as_str() 讓我們 for 迴圈的 arg 引數開始逐一匹配一下內容,如果是 --help 就列印我們的幫助資訊。
  • env!("CARGO_PKG_VERSION") 是一個宏,目的是我們可以列印 關於專案配置裡面的版本號。
  • 在 for 迴圈外列印出錯誤資訊,原因是沒有相關匹配的引數。
  1. 兩個引數
"--hi" => {
    if let Some(name) = args.get(2) {
        println!("hi {}", name);
        return;
    } else {
        println!("錯誤:--hi  需要且僅需要一個名字引數");
        return;
    }
}
  • 我們的 if let Some(name) = args.get(2)
    • 是用 Some 這個列舉型別,簡單來說就是 宣告一個變數,要麼有值:Some(T),要麼為空:None。這是Rust用來替代空指標不安全性的一個特性,非常好用。
    • args.get(2) 我們的 args 是迭代器返回的所有引數,而如果你把這個 args 全部列印出來的話會發現,第一個引數是程式執行的地址,第二個是 --hi 這個引數,第三個才是 NAME 引數,所以我們使用 .get(2) 方法,讓它去獲取這個陣列的第三個元素,也就是索引 2。

原始碼展示

use std::env;

fn main() {
    let help: &str = r#"
      cli 
          --help 幫助,檢視所有引數。
          --version 檢視版本。
          --hi NAME 向你打招呼。
    "#
    // println!("{}", help);

    let args:Vec<String> = env::args().collect();

    for arg in args.iter() {
        match arg.as_str() {
            "--help" => {
                println!("{}", help);
                return;
            },
            "--version" => {
                println!("當前 cli 版本: {}", env!("CARGO_PKG_VERSION"));
                return;
            },
            "--hi" => {
                if let Some(name) = args.get(2) {
                    println!("hi {}", name);
                    return;
                } else {
                    println!("錯誤:--hi  需要且僅需要一個名字引數");
                    return;
                }
            },
            _ => {
                //
            }
        }
    }
    
    println!("未能識別的引數!可以輸入 `cli --help` 來獲取幫助。");

}

相關文章