Rust基础学习笔记(三):编写一个完整的检索程序

今天主要按照Rust圣经的步骤一步一步创建一个简单的文件中检索关键词程序。运用从前学习的知识的同时还有一些新的技巧和知识,摘录如下:

代码布局原则:

主函数只包含基本的调用函数和返回错误,所有的逻辑部分放进同目录下的lib.rs里

测试函数同样也放在lib.rs里.

测试导向编程:

在编写新功能时,可以先编写测试预计功能的测试函数,之后通过调试功能函数使其通过测试。这样就能够简单易懂的完成功能函数的编写。

错误处理:

1.对于返回Result结构的函数,可以利用unwrap_or_not来解包或处理错误。其中还用到了闭包的知识。

let config = Config::new(&args).unwrap_or_else(|err|{
        eprintln!("Problem parsing arguments: {}",err);
        process::exit(1)
    });

2.返回Result函数时可以选择使用Trait对象搭配问号表达式。

pub fn run(config: Config) -> Result<(),Box<dyn Error>>{
    let contents = fs::read_to_string(config.filename)?;
        ...
}

3.使用eprintln!函数输出至标准错误流

(例见1.)

to_uppercase/to_lowercase的返回值是String对象

注意到要与&str的参数类型匹配,在传参的时候用了引用。

环境变量

配置:powershell中输入 $ env:NAME = VALUE 

使用:

 env::var("NAME") 以引用值,后加.iserr()使其当未设定此环境变量时返回true,设定时返回false: env::var("NAME").iserr() 

杂项

Linux语法(?) '>'指向标准输出流的输出文件:

cargo run to poem.txt > output.txt

完整源代码

*本代码完全按照Rust圣经的指导写出。

./src/main.rs

 1 use std::env;
 2 use std::process;
 3 
 4 use minigrep::Config;
 5 
 6 fn main() {
 7     let args: Vec<String> = env::args().collect();
 8 
 9     let config = Config::new(&args).unwrap_or_else(|err|{
10         eprintln!("Problem parsing arguments: {}",err);
11         process::exit(1)
12     });
13 
14     println!("Searching for {}",config.query);
15     println!("In file {}",config.filename);
16 
17     if let Err(e) = minigrep::run(config){
18         eprintln!("Application error: {}", e);
19 
20         process::exit(1);
21     }
22 
23 }

./src/lib.rs

 1 use std::error::Error;
 2 use std::fs;
 3 use std::env;
 4 
 5 pub struct Config{
 6     pub query: String,
 7     pub filename: String,
 8     pub case_sensitive: bool,
 9 }
10 
11 impl Config {
12     pub fn new(args: &[String]) -> Result<Config, &'static str>{
13         if args.len() < 3 {
14             return Err("Not enough arguments!")
15         }
16         let query = args[1].clone();
17         let filename = args[2].clone();
18 
19         let case_sensitive = env::var("CASE_INSENSITIVE").is_err();
20 
21         Ok(Config { query, 
22                     filename,
23                     case_sensitive, })
24     }
25 }
26 
27 pub fn run(config: Config) -> Result<(),Box<dyn Error>>{
28     let contents = fs::read_to_string(config.filename)?;
29 
30     let results = if config.case_sensitive {
31         search(&config.query, &contents)
32     } else {
33         search_case_insensitive(&config.query, &contents)
34     };
35 
36     for line in results {
37         println!("{}", line);
38     }
39 
40     Ok(())
41 }
42 
43 pub fn search<'a>(query: &str, contents: &'a str) ->Vec<&'a str>{
44     let mut results = Vec::new();
45     
46     for line in contents.lines(){
47         if line.contains(query){
48             results.push(line);
49         }
50     }
51 
52     results
53 }
54 
55 pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) ->Vec<&'a str>{
56     let mut results = Vec::new();
57     let query = query.to_lowercase();
58     
59     for line in contents.lines(){
60         if line.to_lowercase().contains(&query){
61             results.push(line);
62         }
63     }
64 
65     results
66 }
67 
68 #[cfg(test)]
69 mod tests {
70     use super::*;
71 
72     #[test]
73     fn case_sensitive(){
74         let query = "duct";
75         let contents = "\
76         Rust:
77 safe, fast, productive.
78 Pick three.
79 Duct tape";
80         
81         assert_eq!(vec!["safe, fast, productive."],search(query,contents));
82     }
83 
84     #[test]
85     fn case_insensitive(){
86         let query = "rUsT";
87         let contents = "\
88         Rust:
89 safe, fast, productive.
90 Pick three.
91 Trust me.";
92         
93         assert_eq!(vec!["Rust:","Trust me."],
94                     search_case_insensitive(query,contents));
95     }
96 }

./poem.txt 为 Emily Dickinson 的诗歌 I'm Nobody! Who are you?

I’m nobody! Who are you?
Are you nobody, too?
Then there’s a pair of us - don’t tell!
They’d banish us, you know.

How dreary to be somebody!
How public, like a frog
To tell your name the livelong day
To an admiring bog!

通过此小程序,大致知晓创建小型项目的基本步骤,盖Rust学习中一路标点,故记之。

posted @ 2020-08-06 14:51  风坞  阅读(521)  评论(0)    收藏  举报