17. 一个I/O项目:构建命令行程序(下)

目录

  • 五、采用测试驱动开发完善库的功能
    • 5.1 编写失败测试用例
    • 5.2 编写成功测试用例
    • 5.3 在run函数中打印搜索到的行
  • 六、添加大小写不敏感功能
  • 七、将错误信息输出到标准错误
  • 八、附录完整代码

五、采用测试驱动开发完善库的功能

5.1 编写失败测试用例

  1. 在lib.rs中写一个简单的search函数
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str>{vec![]
}
  • 目前该函数是一个总是返回空的vector函数;
  • 函数的参数是&str型,因此需要显式地定义生命周期;
  • 生命周期指定contents的生命周期与返回值的相关连;
  1. 在lib.rs中编写测试代码
#[cfg(test)]
mod tests{use super::*;#[test]fn one_result(){let query = "duct";let contents = "\
Rust:
safe, fast, productive.
Pick there.";assert_eq!(vec!["safe, fast, productive."],search(query, contents))}
}
  1. 运行测试会如预期的失败了;

5.2 编写成功测试用例

失败的原因在于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
}
  • 创建一个可变的Vector;
  • 使用字符串类的迭代方法一次读取一行;
  • 在此行中查找,找到后 push进入Vector即可;

编译测试用例
在这里插入图片描述

5.3 在run函数中打印搜索到的行

  • 修改run函数,将搜索到的行内容打印出来
pub fn run(config: Config) -> Result<(), Box<dyn Error>> {let contents = fs::read_to_string(config.filename)?;for line in search(&config.query, &contents) {println!("{}", line);}Ok(())
}

运行命令cargo run body poem.txt,旨在poem.txt文件内查找body字符串
在这里插入图片描述

六、添加大小写不敏感功能

  • 编写大小写不敏感的测试函数search_case_insensitive
  • 将旧的one_result改名为大小写敏感函数case_sensitive

大小写不敏感的search函数

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
}
  • 大小写不敏感的做法就是将读取到的字母以及目标子串全部改为大写或小写;

编写测试函数

#[cfg(test)]
mod tests {use super::*;#[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));}
}

在Config中增加case_sensitive并修改构造函数

use std::env;pub struct Config{query: String,filename: String,case_sensitive: bool, 
}impl Config{pub fn new(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();Ok(Config {query, filename, case_sensitive})}
}
  • 在Config中添加了case_sensitive的布尔值,用来说明是否大小写敏感;
  • 在Config的new函数中使用env::var读取CASE_INSENSITIVE的环境变量设置情况;
  • 如果设置了CASE_INSENSITIVE的值is_err返回True就是大小写不敏感的,否则是敏感的;
  • 注意:不论CASE_INSENSITIVE设置为多少,都是大小写不敏感的

修改run函数,以判断是否起用大小写敏感

pub fn run(config: Config) -> Result<(), Box<dyn Error>> {let contents = fs::read_to_string(config.filename)?;let results = if config.case_sensitive {search(&config.query, &contents)}else{search_case_insensitive(&config.query, &contents)};for line in results{println!("{}", line);}Ok(())
}

测试,先不加环境变量测试大小写敏感的,再测试不敏感的。
在这里插入图片描述

七、将错误信息输出到标准错误

  • 通过println!打印的信息都输出到了终端;
  • 大部分终端都提供了两种输出:标准输出(standard output,stdout)和标准错误(standard error,stderr);
  • 标准输出对应一般信息,标准错误用于错误信息;
  • Rust提供eprintln!宏输出标准错误信息;

修改main的标准错误输出

fn main() {let args: Vec<String> = env::args().collect();let config = Config::new(&args).unwrap_or_else(|err| {eprintln!("Problem parsing arguments: {}", err);process::exit(1);});if let Err(e) = minigrep::run(config) {eprintln!("Application error: {}", e);process::exit(1);}
}

八、附录完整代码

main.rs

use std::env;
use std::process;
use minigrep::Config;fn main() {let args: Vec<String> = env::args().collect();let config = Config::new(&args).unwrap_or_else(|err| {eprintln!("Problem parsing arguments: {}", err);process::exit(1);});if let Err(e) = minigrep::run(config) {eprintln!("Application error: {}", e);process::exit(1);}
}

lib.rs

use std::fs;
use std::env;
use std::error::Error;pub struct Config{query: String,filename: String,case_sensitive: bool, 
}impl Config{pub fn new(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();Ok(Config {query, filename, case_sensitive})}
}pub fn run(config: Config) -> Result<(), Box<dyn Error>> {let contents = fs::read_to_string(config.filename)?;let results = if config.case_sensitive {search(&config.query, &contents)}else{search_case_insensitive(&config.query, &contents)};for line in results{println!("{}", line);}Ok(())
}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
}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
}#[cfg(test)]
mod tests {use super::*;#[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.mzph.cn/diannao/29824.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【算法训练记录——Day31】

Day31——贪心算法Ⅰ 1. 理论1.1 什么是贪心1.2 什么时候用贪心1.3 贪心算法一般步骤 2.leetcode455——分发饼干3.leetcode376——摆动序列 目标&#xff1a; 理论leetcode455——分发饼干leetcode376——摆动序列leetcode53 —— 最大字序和 1. 理论 算法随想录——贪心 1…

c语言---循环 、判断基础知识详解

if语句 else离最近的if语句结合。 if语句题目 //1. 判断一个数是否为奇数 //2. 输出1 - 100之间的奇数 #include <stdio.h> int main() {int n 0;scanf("%d", &n);if (n % 2){printf("奇数\n");}else{printf("不是奇数\n"…

[C#]使用深度学习算法opencvsharp部署RecRecNet广角图像畸变矫正校正摄像广角镜头畸变图像

【论文地址】 https://arxiv.org/abs/2301.01661 【训练源码】 https://github.com/KangLiao929/RecRecNet 【参考源码】 https://github.com/hpc203/recrecnet-opencv-dnn 【算法介绍】 广角镜头在VR技术中显示出诱人的应用&#xff0c;但它会在捕获的图像中引入严重的径…

镜头跟踪的两种方法

方法一 (1) 原理&#xff1a;使球与摄像机保持固定的角度和距离 (2) 给Main Camera添加CamraCtrller.cs组件 public Transform Player;//小球的Transformprivate Vector3 offset;//小球与摄像机位置的偏移&#xff08;在三轴上的距离&#xff09;void Start(){offset Playe…

深度神经网络——什么是降维?

引言 什么是降维&#xff1f; 降维是用于降低数据集维度的过程&#xff0c;采用许多特征并将它们表示为更少的特征。 例如&#xff0c;降维可用于将二十个特征的数据集减少到仅有几个特征。 降维通常用于无监督学习任务 降维是一个用于降低数据集维度的过程&#xff0c;采用许…

c语言指针经典笔试题

指针的笔试题目 //深度讨论数组名 int main1() {int a[] { 1,2,3,4 };printf("%d\n", sizeof(a)); //sizeof内部出现数组名代表是整个数组的大小 //16printf("%d\n", sizeof(a 0)); //首元素地址0还是首元素地址 4/8printf("%d\n", sizeof(*…

TestProject Python SDK入门

2024软件测试面试刷题&#xff0c;这个小程序&#xff08;永久刷题&#xff09;&#xff0c;靠它快速找到工作了&#xff01;&#xff08;刷题APP的天花板&#xff09;-CSDN博客跳槽涨薪的朋友们有福了&#xff0c;今天给大家推荐一个软件测试面试的刷题小程序。​编辑https://…

阻力支撑相对强度(RSRS)选股系列报告之三

https://download.csdn.net/download/SuiZuoZhuLiu/89447699?spm1001.2014.3001.5503https://download.csdn.net/download/SuiZuoZhuLiu/89447699?spm1001.2014.3001.5503

《维汉翻译通》App一款免费的维吾尔语翻译工具,也是新疆人学习中文的利器!维吾尔文OCR识别提取文字神器,功能丰富、界面简洁无广告、操作简单!

免费翻译&#xff0c;无界限沟通 《维汉翻译通》App提供免费的短文本翻译服务&#xff0c;无论是日常对话还是专业术语&#xff0c;都能迅速给出准确的翻译结果。维吾尔语免费翻译工具的加入&#xff0c;更是让这款App成为学习维吾尔语的必备应用。 智能OCR&#xff0c;文字识…

#QT(QCharts绘制曲线)

1.IDE&#xff1a;QTCreator 2.实验&#xff1a;绘制曲线图表 3.记录&#xff1a; 4.代码 pro QT core gui #加入以下代码引入charts QT charts greaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c17# You can make your code fail to compile if it uses depre…

npm发布自己的插件包:新手教程

npm&#xff08;Node Package Manager&#xff09;是Node.js的包管理工具&#xff0c;广泛用于JavaScript项目中。本文将为你介绍如何从零开始发布一个npm插件包。 前提条件 在开始之前&#xff0c;你需要确保以下几点&#xff1a; 安装Node.js和npm&#xff1a;你可以在No…

消息中间件比较:Redis,Kafka和RabbitMQ

对微服务使用异步通信时&#xff0c;通常使用消息代理。代理确保不同微服务之间的通信可靠且稳定&#xff0c;消息在系统内得到管理和监控&#xff0c;并且消息不会丢失。您可以从几个消息代理中进行选择&#xff0c;它们的规模和数据功能各不相同。这篇博文将比较三种最受欢迎…

中医药人工智能大模型正式启动

6月15日&#xff0c;在横琴粤澳深度合作区举行的中医药广东省实验室&#xff08;以下简称横琴实验室&#xff09;第一届学术委员会第一次会议暨首届横琴中医药科技创新大会上&#xff0c;中医药横琴大模型、中药新药智能自动化融合创新平台同时启动。这也是该实验室揭牌半年来取…

迷你手持小风扇十大名牌排名有哪些?公认迷你小风扇排行榜揭开!

随着夏季高温的来临&#xff0c;迷你小风扇成为了大家追求清凉和舒适的必备工具。其小巧便携的设计、强劲的风力和长续航时间&#xff0c;使得迷你小风扇迅速在市场上走红。然而&#xff0c;面对琳琅满目的品牌和各种型号&#xff0c;如何选择一款既高效又耐用的迷你小风扇成为…

UE5 C++ 跑酷游戏练习 Part1

一.修改第三人称模板的 Charactor 1.随鼠标将四处看的功能的输入注释掉。 void ARunGANCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) {// Set up action bindingsif (UEnhancedInputComponent* EnhancedInputComponent CastChecked&…

python+unity手势控制地球大小

效果图如下 具体操作如下 1 在unity窗口添加一个球体 2 给球体添加材质,材质图片使用地球图片 地球图片如下 unity材质设置截图如下 3 编写地球控制脚本 using System.Collections; using System.Collections.Generic; using UnityEngine;public class test : MonoBehavio…

RK3588/算能/Nvidia智能盒子:加速山西铝业智能化转型,保障矿业皮带传输安全稳定运行

近年来&#xff0c;各类矿山事故频发&#xff0c;暴露出传统矿业各环节的诸多问题。随着全国重点产煤省份相继出台相关政策文件&#xff0c;矿业智能化建设进程加快。皮带传输系统升级是矿业智能化的一个重要环节&#xff0c;同时也是降本增效的一个重点方向。 △各省份智能矿山…

《UNIX环境高级编程》第三版(电子工业出版社出品)——两年磨一剑的匠心译作

历时两年&#xff0c;《UNIX环境高级编程》的翻译工作终于落下帷幕。这一路走来&#xff0c;真可谓是如鱼饮水&#xff0c;冷暖自知。还记得最初看到招募译者消息的那一刻&#xff0c;内心的激动难以言表。我毫不犹豫地报名&#xff0c;而后经历了试译、海选等激烈的角逐&#…

基于块生成最大剩余空间的三维装箱算法

问题简介 三维装箱问题&#xff08;3D Bin Packing Problem&#xff0c;3D BPP&#xff09;是一类组合优化问题。它涉及到将一定数量的三维物品放入一个或多个三维容器&#xff08;称为“箱子”&#xff09;中&#xff0c;同时遵循一定的约束&#xff0c;通常目标是最大化空间…

后端开发中缓存的作用以及基于Spring框架演示实现缓存

缓存的作用及演示 现在我们使用的程序都是通过去数据库里拿数据然后展示的 长期对数据库进行数据访问 这样数据库的压力会越来越大 数据库扛不住了 创建了一个新的区域 程序访问去缓存 缓存区数据库 缓存里放数据 有效降低数据访问的压力 我们首先进行一个演示 为了演示…