關於學習了 Rust 一些基礎語法,想寫一個 demo 來鞏固一下基礎的語法知識,想到了可以寫一個 CLI 小工具。
大致思路
- cli 工具如執行
cli --help
可以列印出命令、引數幫助。 - cli 工具的引數可能不止一個 如
cli --hi NAME
,列印的結果應該是hi 你的名字
。
這就是一個簡單的 cli 工具的實現,我們會且僅用到標準庫,如果覺得功能不夠,可以自行新增,如 執行一個命令 可以往 Windows 的 HOST 新增內容,就需要用到 Rust 的 I/O。
開始實現
- 導包
首先我們匯入標準庫,我們會用到 std::env
下的 Args 結構體,它是 程序引數的迭代器,為每個引數產生 String
值。
use std::env;
fn main() {
}
- 定義 Help 內容
let help: &str = r#"
cli
--help 幫助,檢視所有引數。
--version 檢視版本。
--hi NAME 向你打招呼。
"#
// 這裡我們使用 r#""# 不僅方便更鞏固 Rust 字串相關的知識點。
- 程式引數迭代器的使用
let args: Vec<String> = env::args().collect();
此處我們宣告一個名為 agrs ,值為String型別的向量,因為迭代器返回的是一串 String 型別的內容。
.collect()
方法就是去收集這些引數。
- 開始匹配引數
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 迴圈外列印出錯誤資訊,原因是沒有相關匹配的引數。
- 兩個引數
"--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` 來獲取幫助。");
}