当前位置: 首页 > news >正文

Rust6.2 An I/O Project: Building a Command Line Program (mini_grep)

Rust学习笔记

Rust编程语言入门教程课程笔记

参考教材: The Rust Programming Language (by Steve Klabnik and Carol Nichols, with contributions from the Rust Community)

Lecture 12: An I/O Project: Building a Command Line Program

project: minigrep

src/main.rs

//grep: globally search a regular expression and printuse std::env;//command line arguments
use std::process;//exituse minigrep::Config;//Config struct
use minigrep::run;//run function//Separation of Concerns for Binary Projects
//Splitting code into a main.rs and a lib.rs is a good default choice when starting a binary project.//1. Split your program into a main.rs and a lib.rs and move your program’s logic to lib.rs.
//2. As long as your command line parsing logic is small, it can remain in main.rs.
//3. When the command line parsing logic starts getting complicated, extract it from main.rs and move it to lib.rs.fn main() {let args: Vec<String> = env::args().collect();//collect command line arguments// println!("{:?}", args);//print command line arguments //[./target/debug/minigrep, xxxx, yyyy]// let query = &args[1];//query string // let filename = &args[2];//filename//let (query, filename) = parse_config(&args[1..]);//parse command line arguments// let config = parse_config(&args);//parse command line arguments// let config = Config::new(&args);//parse command line argumentslet config = Config::build(&args).unwrap_or_else(|err| {// println!("Problem parsing arguments: {}", err);eprintln!("Problem parsing arguments: {}", err);//error handling: print to stderrprocess::exit(1);});//parse command line arguments// println!("Searching for {}", query);// println!("In file {}", filename);// let contents = fs::read_to_string(config.filename)//     .expect("Something went wrong reading the file");//read file// println!("With text:\n{}", contents);if let Err(e) = run(config){// println!("Application error: {}", e);eprintln!("Application error: {}", e);//error handling: print to stderrprocess::exit(1);}
}

lib.rs

use std::fs;//file system
use std::error::Error;//error handling
use std::env;//environment variables// fn parse_config(args: &[String]) -> (&str, &str) {
//     let query = &args[1];//query string 
//     let filename = &args[2];//filename//     (query, filename)
// }pub fn run(config: Config) -> Result<(), Box<dyn Error>>{let contents = fs::read_to_string(config.filename)?;//.expect("Something went wrong reading the file");//read file//println!("With text:\n{}", contents);let results = if config.case_sensitive {//if case sensitivesearch(&config.query, &contents)//search case sensitive} else {search_case_insensitive(&config.query, &contents)//search case insensitive};// for line in search(&config.query, &contents) {//iterate over each line//     println!("{}", line);//print line// }for line in results {//iterate over each lineprintln!("{}", line);//print line}Ok(())
}pub struct Config {query: String,filename: String,case_sensitive: bool,
}// fn parse_config(args: &[String]) -> Config {
//     let query = args[1].clone();//query string 
//     let filename = args[2].clone();//filename//     Config { query, filename }
// }impl Config {// fn new(args: &[String]) -> Config {//     if args.len() < 3 {//         panic!("not enough arguments");//     }//     let query = args[1].clone();//query string //     let filename = args[2].clone();//filename//     Config { query, filename }// }pub fn build(args: &[String]) -> Result<Config, &'static str> {if args.len() < 3 {return Err("not enough arguments");}let query = args[1].clone();let filename = args[2].clone();let case_sensitive = env::var("CASE_INSENSITIVE").is_err();//case sensitiveOk(Config { query, filename, case_sensitive })}
}pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {//<'a> lifetime annotation// let mut results = Vec::new();//mutable vector// for line in contents.lines() {//iterate over each line//     if line.contains(query) {//if line contains query//         results.push(line);//add line to results//     }// }// results//return resultscontents.lines()//iterate over each line.filter(|line| line.contains(query))//if line contains query.collect()//collect into vector
}pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {//<'a> lifetime annotationlet mut results = Vec::new();//mutable vectorlet query = query.to_lowercase();//convert query to lowercasefor line in contents.lines() {//iterate over each lineif line.to_lowercase().contains(&query) {//if line contains queryresults.push(line);//add line to results}}results//return results
}//TDD: Test-Driven Development 
//Writing a Failing Test and Seeing It Pass
//1. Write a test that fails and run it to make sure it fails for the reason you expect.
//2. Write or modify just enough code to make the new test pass.
//3. Refactor the code you just added or changed and make sure the tests continue to pass.
//4. Repeat from step 1!#[cfg(test)]
mod tests {use super::*;//import outer scope#[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 case_sensitive() {let query = "duct";let contents = "\
Rust:
safe, fast, productive.
Pick three.
Duct tape.";assert_eq!(vec!["safe, fast, productive."],search(query, contents));}#[test]fn case_insensitive() {let query = "rUsT";let contents = "\
Rust:
safe, fast, productive.
Pick three.
Trust me.";assert_eq!(vec!["Rust:", "Trust me."],search_case_insensitive(query, contents));}
}
http://www.lryc.cn/news/235998.html

相关文章:

  • 云轴科技ZStack信创云平台支撑长江航务管理局35套航运管理系统
  • Canal+Kafka实现MySQL与Redis数据同步(一)
  • 集合的运算
  • 在MySQL上实现间隔5分钟汇总取数及相关字符串、时间处理方法实践
  • 什么是AIGC
  • 〖大前端 - 基础入门三大核心之JS篇㊳〗- DOM访问元素节点
  • GitHub Universe 2023:AI 技术引领软件开发创新浪潮
  • 数据结构:红黑树的插入实现(C++)
  • 飞天使-django之数据库简介
  • Flink之KeyedState
  • c语言:模拟实现qsort函数
  • 从0开始学习数据结构 C语言实现 1.前篇及二分查找算法
  • VSCode 使用CMakePreset找不到cl.exe编译器的问题
  • 【Linux系统化学习】进程的状态 | 僵尸进程 | 孤儿进程
  • 深信服AC流量管理技术
  • 二元关系及关系代数中的象集、除运算
  • [PHP]关联和操作MySQL数据库然后将数据库部署到ECS
  • 23.11.19日总结
  • 系列一、JVM概述
  • milvus数据管理-压缩数据
  • SpringBoot项目连接linux服务器数据库两种解决方法(linux直接开放端口访问本机通过SSH协议访问,以mysql为例)
  • 【Rust】快速教程——闭包与生命周期
  • redis高级案列case
  • Vue3+Vite实现工程化,attribute属性渲染v-bind指令
  • 下一代搜索引擎会什么?
  • WPF中如何在MVVM模式下关闭窗口
  • 【数据结构&C++】二叉平衡搜索树-AVL树(25)
  • Python算法——树的最大深度和最小深度
  • 46.全排列-py
  • 系列三、GC垃圾回收算法和垃圾收集器的关系?分别是什么请你谈谈