首页 > 编程语言 > 详细

[易学易懂系列|rustlang语言|零基础|快速入门|(25)|实战2:命令行工具minigrep(2)]

时间:2019-12-19 17:04:18      阅读:109      评论:0      收藏:0      [点我收藏+]

[易学易懂系列|rustlang语言|零基础|快速入门|(25)|实战2:命令行工具minigrep(2)]

项目实战

实战2:命令行工具minigrep

我们继续开发我们的minigrep。

我们现在以TDD测试驱动开发的模式,来开发新的功能search函数。

开始吧,我们先在src/lib.rs文件中,增加测试代码:

#[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));
    }
}

然后同样再写一个空函数:

pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    vec![]
}

然后,我们要跑一下命令:

cargo test

结果显示:

$ cargo test
   Compiling minigrep v0.1.0 (file:///projects/minigrep)
--warnings--
    Finished dev [unoptimized + debuginfo] target(s) in 0.43 secs
     Running target/debug/deps/minigrep-abcabcabc

running 1 test
test tests::one_result ... FAILED

failures:

---- tests::one_result stdout ----
        thread 'tests::one_result' panicked at 'assertion failed: `(left ==
right)`
left: `["safe, fast, productive."]`,
right: `[]`)', src/lib.rs:48:8
note: Run with `RUST_BACKTRACE=1` for a backtrace.


failures:
    tests::one_result

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

error: test failed, to rerun pass '--lib'

测试不通过。

我们的实现函数search,只简单返回一个空vector。当然,不通过。

怎么办?

重构一下search函数:

pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    let mut results = Vec::new();

    for line in contents.lines() {
        if line.contains(query) {
            results.push(line);
        }
    }

    results
}

然后,我们跑一下命令:

cargo test

结果显示:

running 1 test
test tests::one_result ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

测试通过!漂亮!

这就是TDD的基本流程。

我们看看示图:

技术分享图片

好吧,现在我们可以直接调用search函数了,把它放到src/lib.rs中的run函数里:

//重构从文件中读取内容的业务逻辑
pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
    let contents = fs::read_to_string(config.filename)?;

    println!("With text:\n{}", contents);

    for line in search(&config.query, &contents) {
       println!("-----search result ------{}", line);
    }
    Ok(())
}

然后,我们用运行命令:

cargo run frog poem.txt

结果为:

.......
-----search result ------How public, like a frog

我们找到包含frog单词的那一行!完美!

我们再找下body单词:

cargo run body poem.txt

结果为:

......
-----search result ------I'm nobody! Who are you?
-----search result ------Are you nobody, too?
-----search result ------How dreary to be somebody!

结果正确!

当然,我们也可以试试不存在的单词:

cargo run monomorphization poem.txt

结果为:

E:\code\rustProject\minigrep> cargo run monomorphization poem.txt
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target\debug\minigrep.exe monomorphization poem.txt`
With text:
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!

没有出现带“-----search result ------”的结果信息,说明没有找到单词:monomorphization。

结果符合期望。

现在我们再以TDD的开发方式来开发新的功能函数search_case_insensitive,新增测试代码:

#[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)
    );
}

当然,我们可以简单实现一下search_case_insensitive函数,让它fail,因为这个逻辑比较简单,那就直接实现吧:

pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    let query = query.to_lowercase();
    let mut results = Vec::new();

    for line in contents.lines() {
        if line.to_lowercase().contains(&query) {
            results.push(line);
        }
    }

    results
}

好的,我们跑一下命令:

cargo test

结果:

$cargo test
   Compiling minigrep v0.1.0 (E:\code\rustProject\minigrep)
    Finished dev [unoptimized + debuginfo] target(s) in 1.38s
     Running target\debug\deps\minigrep-07da7ef1bffd9ef9.exe

running 2 tests
test case_insensitive ... ok
test tests::one_result ... ok

测试通过,漂亮!

以上,希望对你有用。

如果遇到什么问题,欢迎加入:rust新手群,在这里我可以提供一些简单的帮助,加微信:360369487,注明:博客园+rust

参考文章:

https://doc.rust-lang.org/stable/book/ch12-05-working-with-environment-variables.html

[易学易懂系列|rustlang语言|零基础|快速入门|(25)|实战2:命令行工具minigrep(2)]

原文:https://www.cnblogs.com/gyc567/p/12068718.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!