如何基于Rust實現(xiàn)文本搜索minigrep
在Rust學習社區(qū)看到了 用Rust語言實現(xiàn)的minigrep,對于初學者的我來說,這個項目很感興趣,于是跟著實現(xiàn)了一遍,并完善了一點邏輯,以下是對項目的介紹
效果展示
本次演示介紹針對原作者代碼程序的查詢邏輯做了一點點小的優(yōu)化,原程序邏輯的查詢是放在了程序運行的時候,邏輯修改后啟動的時候可以添加參數(shù),也可以啟動后添加,具體如下
修改前
查詢時 需要輸入查詢的字符串和文件cargo run -- th poem.txt
修改后
啟動程序:cargo run
輸入要查詢的字符串 th
輸入要查詢的文件路徑 poem.txt
查詢到的結(jié)果:
Then there’s a pair of us - don’t tell!
They’d banish us, you know.
To tell your name the livelong day退出程序:輸入:q
如下圖所示
代碼實現(xiàn)
代碼結(jié)構(gòu)
minigrep ├── Cargo.lock ├── Cargo.toml ├── output.txt ├── poem.txt ├── src ├── lib.rs └── main.rs
代碼展示
/src/main.rs
use std::{env, process}; use std::io::stdin; use minigrep::Config; fn main() { let args: Vec<String> = env::args().collect(); if args.len() == 1 { // 如果沒輸入查詢參數(shù),就循環(huán)等待用戶的輸入 loop { println!("請輸入要查詢的字符串:"); // 等待用戶輸入 let mut input = String::new(); stdin().read_line(&mut input).expect("無法讀取"); let mut args = input.split_whitespace(); let mut a = String::new(); let query = args.next().unwrap_or_else(|| { println!("請輸入有效的查詢字符串"); stdin().read_line(&mut a); &a.as_str().trim() }); if(":q".eq(query.clone())){ println!("程序退出"); process::exit(1); } let mut a = String::new(); let file_path = args.next().unwrap_or_else(|| { println!("請輸入文件路徑:"); stdin().read_line(&mut a); &a.as_str().trim() }); let config1 = Config { query: query.to_string(), file_path: file_path.to_string(), ignore_case: true }; if let Err(e) = minigrep::run(config1) { eprintln!("程序出錯:{e}"); } } } else { // 啟動時的入?yún)? let config = Config::build(env::args()).unwrap_or_else(|err| { eprintln!("程序解析 參數(shù)異常 {err}"); process::exit(1); }); println!("search for {}", config.query); println!("in file {}", config.file_path); if let Err(e) = minigrep::run(config) { eprintln!("程序出錯:{e}"); process::exit(1); } } }
/src/lib.rs
use std::error::Error; use std::{env, fs}; // 查詢業(yè)務邏輯 pub fn run(config: Config) -> Result<(), Box<dyn Error>> { if let Ok(contents) = fs::read_to_string(config.file_path){ let lines = if config.ignore_case { search_case_insensitive(&config.query, &contents) } else { search(&config.query, &contents) }; println!("查詢到的結(jié)果:"); for line in lines { println!("{line}") } Ok(()) }else { Err(Box::from("未查詢到文件")) } } // 配置實體 pub struct Config { pub query: String, pub file_path: String, pub ignore_case:bool, } impl Config { // 構(gòu)建配置實體 pub fn build(mut args: impl Iterator<Item =String>) -> Result<Config, &'static str> { let _programeName = args.next(); let query = match args.next() { Some(query) => query, None => return Err("未獲取到 要查詢的 字符串參數(shù)"), }; let file_path = match args.next() { Some(file_path) => file_path, None => return Err("未獲取到文件路徑"), }; // 從環(huán)境變量中找到是否包含 IGNORE_CASE let ignore_case = env::var("IGNORE_CASE").is_ok(); Ok(Config { query, file_path ,ignore_case}) } } // 對參數(shù)解析 fn parse_config(args: &[String]) -> Config { let query = args[1].clone(); let file_path = args[2].clone(); let ignore_case = env::var("IGNORE_CASE").is_ok(); Config { query, file_path ,ignore_case} } // 大小寫敏感查詢 pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { contents .lines() .filter(|line| line.contains(query)) .collect() } // 忽略大小寫查詢 pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { contents .lines() .filter(|line| line.to_lowercase().contains(&query.to_lowercase())) .collect() } // 測試模塊 #[cfg(test)] mod tests { use super::*; #[test] fn one_result() { let query = "duct"; let contents = "\ Rust: safe, fast, productive. Pick three."; assert_eq!(vec!["safe, fast, productive."], search(query, contents)) } #[test] fn test_case_insensitive() { let query = "RusT"; let contents = "\ Rust: safe, fast, productive. Pick three."; assert_eq!(vec!["Rust:"], search_case_insensitive(query, contents)) } }
到此這篇關(guān)于基于Rust實現(xiàn)的文本搜索minigrep的文章就介紹到這了,更多相關(guān)Rust 文本搜索minigrep內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Rust調(diào)用Windows API 如何獲取正在運行的全部進程信息
本文介紹了如何使用Rust調(diào)用WindowsAPI獲取正在運行的全部進程信息,通過引入winapi依賴并添加相應的features,可以實現(xiàn)對不同API集的調(diào)用,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-11-11Rust實現(xiàn)構(gòu)建器模式和如何使用Bon庫中的構(gòu)建器
這篇文章主要介紹了Rust實現(xiàn)構(gòu)建器模式和如何使用Bon庫中的構(gòu)建器,本文給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-08-08在win10上使用mingw64編譯器配置Rust開發(fā)環(huán)境和idea 配置Rust 插件
在win10上配置 Rust 開發(fā)環(huán)境(使用 mingw64編譯器)和 idea 配置 Rust 插件的相關(guān)知識,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2023-03-03關(guān)于Rust?使用?dotenv?來設置環(huán)境變量的問題
在項目中,我們通常需要設置一些環(huán)境變量,用來保存一些憑證或其它數(shù)據(jù),這時我們可以使用dotenv這個crate,接下來通過本文給大家介紹Rust?使用dotenv來設置環(huán)境變量的問題,感興趣的朋友一起看看吧2022-01-01Rust 連接 SQLite 數(shù)據(jù)庫的過程解析
本文通過一個例子給大家介紹了Rust 連接 SQLite 數(shù)據(jù)庫的詳細過程,我使用rusqlite這個crate,對Rust 連接 SQLite 數(shù)據(jù)庫相關(guān)知識感興趣的朋友跟隨小編一起看看吧2022-01-01