關(guān)于Rust命令行參數(shù)解析以minigrep為例
一、新建項(xiàng)目
和往常一樣,我們先用 cargo new minigrep 創(chuàng)建一個(gè)新的二進(jìn)制項(xiàng)目:
$ cargo new minigrep $ cd minigrep
Cargo 自動(dòng)幫我們生成了一個(gè)基礎(chǔ)的 src/main.rs 文件,里面有一個(gè)簡(jiǎn)單的 “Hello, world!” 示例。我們會(huì)在此文件中編寫(xiě)命令行解析的邏輯。
二、獲取命令行參數(shù)
要想在 Rust 中讀取命令行參數(shù),可以使用標(biāo)準(zhǔn)庫(kù)的 std::env::args 函數(shù)。
此函數(shù)會(huì)返回一個(gè)迭代器(iterator),包含程序啟動(dòng)時(shí)傳遞給它的所有命令行參數(shù)。
以下為一個(gè)最簡(jiǎn)單的示例(src/main.rs):
use std::env;
fn main() {
let args: Vec<String> = env::args().collect();
println!("{:?}", args);
}我們?cè)谏厦孀隽藥准拢?/p>
use std::env;:將std::env模塊引入當(dāng)前作用域,以便使用env::args。env::args():此函數(shù)返回一個(gè)迭代器,能夠依次提供命令行參數(shù)。collect():把迭代器轉(zhuǎn)換為一個(gè)包含所有參數(shù)的Vec<String>。println!("{:?}", args);:采用調(diào)試模式打印整個(gè)向量,驗(yàn)證它的內(nèi)容。
運(yùn)行結(jié)果演示
我們先不傳參數(shù)來(lái)看看默認(rèn)輸出:
$ cargo run
Compiling minigrep v0.1.0 (~/minigrep)
Finished dev [unoptimized + debuginfo] target(s) in 0.37s
Running `target/debug/minigrep`
["target/debug/minigrep"]可以看到,向量的第一個(gè)元素是可執(zhí)行文件的路徑或名稱(chēng)(類(lèi)似于 C 語(yǔ)言中的 argv[0])。
如果我們傳入兩個(gè)額外參數(shù)試試:
$ cargo run -- rust sample.txt ... ["target/debug/minigrep", "rust", "sample.txt"]
Rust 程序可獲取我們?cè)诿钚休斎氲?“rust” 和 “sample.txt” 兩個(gè)參數(shù)。
這里要注意 -- 的用法:cargo run -- <args> 表示 -- 后面的內(nèi)容是傳給編譯出來(lái)的程序本身,而非 cargo run 命令的參數(shù)。
三、將參數(shù)存入變量
打印出所有參數(shù)后,我們往往只關(guān)心其中的部分信息。比如在“minigrep”工具里,我們希望接收兩個(gè)參數(shù):
- 查詢(xún)字符串(query):要搜索的單詞或模式;
- 文件名(file_path):要在其中搜索的文件。
那么就可以在 main 函數(shù)中把參數(shù)按順序賦給變量。
示例代碼如下:
use std::env;
fn main() {
let args: Vec<String> = env::args().collect();
// args[0] 是程序本身 ("target/debug/minigrep")
let query = &args[1]; // 第一個(gè)實(shí)際參數(shù)
let file_path = &args[2]; // 第二個(gè)實(shí)際參數(shù)
println!("Searching for: {}", query);
println!("In file: {}", file_path);
}運(yùn)行并驗(yàn)證
$ cargo run -- to-do-list tasks.txt
Finished dev [unoptimized + debuginfo] target(s) in 0.24s
Running `target/debug/minigrep to-do-list tasks.txt`
Searching for: to-do-list
In file: tasks.txt可以看到,程序正確地抓取到 “to-do-list” 和 “tasks.txt”。接下來(lái),我們就能利用這兩個(gè)變量為后續(xù)的文件處理和搜索邏輯作準(zhǔn)備。
提示:如果要支持包含 Unicode 無(wú)效字符的參數(shù),std::env::args 會(huì)在遇到無(wú)效 Unicode 時(shí)觸發(fā) panic!。此時(shí),可使用 std::env::args_os 返回 OsString,從而更好地兼容各平臺(tái)。但在一般使用場(chǎng)景下,args 足夠滿足需求。
四、下一步:處理文件和搜索邏輯
在實(shí)際項(xiàng)目中,拿到 query 和 file_path 兩個(gè)參數(shù)后,我們往往會(huì)繼續(xù)執(zhí)行下列操作:
- 讀取文件內(nèi)容:使用
std::fs::read_to_string或者文件 IO 相關(guān) API。 - 搜索匹配項(xiàng):對(duì)文件內(nèi)容逐行(或整體)進(jìn)行查找,找出與
query相匹配的部分。 - 輸出搜索結(jié)果:根據(jù)需要將匹配到的行打印出來(lái),或統(tǒng)計(jì)匹配數(shù)量等等。
后續(xù)還應(yīng)考慮更加健壯的錯(cuò)誤處理方式,比如:
- 未提供足夠的命令行參數(shù)時(shí),給出友好的提示信息;
- 文件無(wú)法打開(kāi)或讀取時(shí)如何提示并退出;
- 搜索字符串為空時(shí)是否給用戶(hù)警告等。
五、總結(jié)
Rust 標(biāo)準(zhǔn)庫(kù)為命令行參數(shù)處理提供了一個(gè)非常簡(jiǎn)潔的入口——std::env::args()。借助迭代器和 collect(),我們可以快速拿到一個(gè) Vec<String>,隨后就能像操作數(shù)組一樣輕松讀取或處理參數(shù)。同時(shí),你也可以借助社區(qū) crates(如 clap、structopt 等)在復(fù)雜命令行解析場(chǎng)景下更快上手。
在本文示例中,我們初步實(shí)現(xiàn)了一個(gè)迷你“grep”程序的命令行參數(shù)獲取:它能接收一個(gè)搜索關(guān)鍵字和一個(gè)文件名,后續(xù)我們還會(huì)進(jìn)一步完善其搜索功能、文件處理及錯(cuò)誤處理等邏輯。相信通過(guò)這個(gè)小練習(xí),你已經(jīng)了解并掌握了 Rust 如何在命令行工具中優(yōu)雅地處理參數(shù)輸入!
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Rust語(yǔ)言實(shí)現(xiàn)圖像編碼轉(zhuǎn)換
image-rs庫(kù)是?Rust?社區(qū)中廣泛使用的一個(gè)開(kāi)源庫(kù),它提供了豐富的圖像編解碼功能,本文主要介紹了Rust語(yǔ)言實(shí)現(xiàn)圖像編碼轉(zhuǎn)換,具有一定的參考價(jià)值,感興趣的可以了解一下2024-05-05
Rust語(yǔ)言從入門(mén)到精通系列之Iterator迭代器深入詳解
這篇文章主要為大家介紹了Rust語(yǔ)言從入門(mén)到精通系列之Iterator迭代器深入詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
利用rust實(shí)現(xiàn)一個(gè)命令行工具
這篇文章主要為大家詳細(xì)介紹了如何使用?Rust?和?clap?4.4.0?創(chuàng)建一個(gè)命令行工具?my_dev_tool,文中的示例代碼講解詳細(xì),需要的小伙伴可以參考下2023-12-12
如何使用rust實(shí)現(xiàn)簡(jiǎn)單的單鏈表
實(shí)現(xiàn)單鏈表在別的語(yǔ)言里面可能是一件簡(jiǎn)單的事情,單對(duì)于Rust來(lái)說(shuō),絕對(duì)不簡(jiǎn)單,下面這篇文章主要給大家介紹了關(guān)于如何使用rust實(shí)現(xiàn)簡(jiǎn)單的單鏈表的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-03-03
Rust使用Sled添加高性能嵌入式數(shù)據(jù)庫(kù)
這篇文章主要為大家詳細(xì)介紹了如何在Rust項(xiàng)目中使用Sled庫(kù),一個(gè)為Rust生態(tài)設(shè)計(jì)的現(xiàn)代、高性能嵌入式數(shù)據(jù)庫(kù),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03
在Rust中編寫(xiě)自定義Error的詳細(xì)代碼
Result<T, E> 類(lèi)型可以方便地用于錯(cuò)誤傳導(dǎo),Result<T, E>是模板類(lèi)型,實(shí)例化后可以是各種類(lèi)型,但 Rust 要求傳導(dǎo)的 Result 中的 E 是相同類(lèi)型的,所以我們需要編寫(xiě)自己的 Error 類(lèi)型,本文給大家介紹了在Rust中編寫(xiě)自定義Error的詳細(xì)代碼,需要的朋友可以參考下2024-01-01
Rust中用enum實(shí)現(xiàn)多參數(shù)Hook機(jī)制完整代碼
在 Rust 中,如果想為enum實(shí)現(xiàn)一個(gè)帶多參數(shù)的 Hook 機(jī)制,可以結(jié)合模式匹配和枚舉來(lái)處理,這種方式可以擴(kuò)展到支持不同類(lèi)型的輸入?yún)?shù)和邏輯處理,下面通過(guò)示例代碼介紹Rust中用enum實(shí)現(xiàn)多參數(shù)Hook機(jī)制,感興趣的朋友一起看看吧2024-12-12

