Rust 初体验4

《Rust语言圣经》入门实战的前两节中,介绍了 minigrep 程序设计过程,包括命令行设计、参数接收、文件读取、模块化和错误处理等。其功能是从指定文件中查找字符串。

代码包括两部分:main.rs,lib.rs。下面对代码简单做了注释。

main.rs

// 引入标准库中的环境变量和进程处理模块
use std::env;
use std::process;
// 引入自定义的minigrep模块中的Config结构体
use minigrep::Config;// 主函数
fn main() {// 获取命令行参数并存储到Vec<String>类型的args中let args: Vec<String> = env::args().collect();// 使用Config::build方法解析命令行参数,如果解析失败则打印错误信息并退出程序let config = Config::build(&args).unwrap_or_else(|err|{println!("Problem parsing arguments: {}", err);process::exit(1)});// 打印搜索关键词和文件名println!("Searching for {}", config.query);println!(" in file {}", config.filename);// 调用minigrep模块的run方法执行搜索操作,如果发生错误则打印错误信息并退出程序if let Err(e) = minigrep::run(config){println!("Application error: {}", e);process::exit(1);}// 程序正常结束,退出状态码为0process::exit(0);
}

lib 模块

// 导入标准库中的文件系统模块和错误处理模块
use std::fs;
use std::error::Error;// 定义一个名为Config的结构体,包含两个公共字段:query和filename
pub struct Config {pub query: String,pub filename: String,
}// 为Config结构体实现一个名为build的方法,接收一个字符串切片作为参数,返回Result类型
impl Config{// build方法用于根据传入的参数构建Config实例pub fn build(args: &[String]) -> Result<Config, &'static str> {// 如果参数数量小于3,返回错误信息if args.len() < 3 {return Err("Not enough arguments");}// 获取查询字符串和文件名let query = args[1].clone();let filename = args[2].clone();// 返回构建好的Config实例Ok(Config{ query, filename })}
}// 定义一个名为run的函数,接收一个Config实例作为参数,返回Result类型
pub fn run(config: Config) -> Result<(), Box<dyn Error>> {// 读取文件内容到字符串中,如果出错则抛出异常let contents = fs::read_to_string(config.filename) .expect("Something went wrong reading the file");// 打印文件内容println!("With text:{}", contents);// 返回成功Ok(())
}

代码说明

main.rs模块

  1. 引入了标准库中的环境变量和进程处理模块。
  2. 引入了自定义的minigrep模块中的Config结构体。
  3. 定义了主函数main()。
  4. 获取命令行参数并存储到Vec类型的args中。
  5. 使用Config::build方法解析命令行参数,如果解析失败则打印错误信息并退出程序。
  6. 打印搜索关键词和文件名。
  7. 调用minigrep模块的run方法执行搜索操作,如果发生错误则打印错误信息并退出程序。
  8. 程序正常结束,退出状态码为0。

lib.rs模块

  1. 导入了标准库中的文件系统模块和错误处理模块。
  2. 定义了一个名为Config的结构体,包含两个公共字段:query和filename。
  3. 为Config结构体实现了一个名为build的方法,接收一个字符串切片作为参数,返回Result类型。该方法用于根据传入的参数构建Config实例。
  4. 定义了一个名为run的函数,接收一个Config实例作为参数,返回Result类型。该函数用于读取文件内容并在控制台打印出来。

关于错误处理

在以上代码中,错误处理主要通过Result类型和unwrap_or_else方法来实现。

  1. Result类型:用于表示一个操作可能成功或失败的结果。它有两个变体:Ok表示操作成功,并包含成功时的值;Err表示操作失败,并包含失败的原因。

  2. unwrap_or_else方法:该方法用于处理Result类型的结果。如果结果是Ok,则返回Ok中的值;如果结果是Err,则执行传入的闭包函数,并返回该函数的结果。在这个例子中,当Config::build方法返回Err时,会执行闭包函数,打印错误信息并退出程序。

例如,在main.rs模块中,以下代码段:

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

这里使用了unwrap_or_else方法来处理Config::build方法的返回结果。如果build方法返回Ok,那么config变量将被赋值为Ok中的Config实例;如果build方法返回Err,那么将执行闭包函数,打印错误信息并退出程序。

lib.rs模块中:

if let Err(e) = minigrep::run(config){println!("Application error: {}", e);process::exit(1);
}

这里使用了if let语句来处理minigrep::run方法的返回结果。如果run方法返回Ok,那么程序将继续执行;如果run方法返回Err,那么将执行闭包函数,打印错误信息并退出程序。

Result 泛型

Result<(), Box<dyn Error>> 是一个泛型类型,用于表示一个操作可能成功或失败的结果。它有两个变体:Ok表示操作成功,并包含成功时的值;Err表示操作失败,并包含失败的原因。

在这个例子中,Result的类型参数是(),表示操作成功时没有返回值。错误类型是Box<dyn Error>,其中Box表示一个堆分配的指针,而dyn Error表示任何实现了Error trait的类型。这意味着这个Result可以容纳任何实现了Error trait的错误类型。

这种类型的Result通常用于那些不需要返回具体值的操作,只需要表示操作是否成功。例如,在minigrep::run函数中,它返回Result<(), Box<dyn Error>>,表示该函数执行搜索操作,如果成功则不返回任何值(Ok(())),如果失败则返回一个实现了Error trait的错误类型(Err(error))

关于Error trait

Rust中用于表示错误的标准接口。它定义了一组方法,用于处理错误和获取关于错误的信息。Error trait 常用方法:

  1. description:返回一个字符串切片,描述了错误的细节。
  2. cause:返回一个Option类型的值,包含导致当前错误的原始错误。如果当前错误没有原因,则返回None。
  3. source:返回一个Option类型的值,包含导致当前错误的原始错误。与cause方法类似,但source方法提供了更多的上下文信息。
  4. chain:返回一个Option类型的值,包含一个错误链表,描述了导致当前错误的多个原始错误。如果当前错误没有原因,则返回None。
  5. backtrace:返回一个Option类型的值,包含当前错误的回溯信息。这对于调试和定位错误非常有用。
  6. to_string:返回一个字符串,包含了关于当前错误的详细信息。这个字符串通常包含了description、cause、source、chain和backtrace等方法的信息。

要实现Error trait,类型需要提供上述方法的具体实现。Rust的标准库中已经为许多内置类型实现了Error trait,例如std::io::Error、std::num::ParseIntError等。用户也可以为自己的类型实现Error trait,以便在错误处理中使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/685842.shtml

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

相关文章

N-144基于微信小程序在线订餐系统

开发工具&#xff1a;IDEA、微信小程序 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 前端技术&#xff1a;vue、ElementUI、 Vant Weapp 服务端技术&#xff1a;springbootmybatisredis 本系统分微信小程序和…

luigi,一个好用的 Python 数据管道库!

🏷️个人主页:鼠鼠我捏,要死了捏的主页 🏷️付费专栏:Python专栏 🏷️个人学习笔记,若有缺误,欢迎评论区指正 前言 大家好,今天为大家分享一个超级厉害的 Python 库 - luigi。 Github地址:https://github.com/spotify/luigi 在大数据时代,处理海量数据已经成…

Attention Is All Your Need论文笔记

论文解决了什么问题&#xff1f; 提出了一个新的简单网络架构——transformer&#xff0c;仅仅是基于注意力机制&#xff0c;完全免去递推和卷积&#xff0c;使得神经网络训练地速度极大地提高。 We propose a new simple network architecture, the Transformer, based sole…

Rust 学习笔记 - 变量声明与使用

前言 任何一门编程语言几乎都脱离不了&#xff1a;变量、基本类型、函数、注释、循环、条件判断&#xff0c;这是一门编程语言的语法基础&#xff0c;只有当掌握这些基础语法及概念才能更好的学习 Rust。 变量介绍 Rust 是一种强类型语言&#xff0c;但在声明变量时&#xf…

UI风格汇:毛玻璃风格风靡的原因解读

Hello&#xff0c;我是大千UI工场&#xff0c;设计风格是我们新开辟的栏目&#xff0c;主要讲解各类UI风格特征、辨识方法、应用场景、运用方法等&#xff0c;本次带来的是毛玻璃风格的解读&#xff0c;有设计需求可以私聊。 一、什么是毛玻璃风格 毛玻璃风格&#xff08;Fros…

lazarus:LCL 嵌入 fpwebview 组件,做一个简单浏览器

从 https://github.com/PierceNg/fpwebview 下载 fpwebview-master.zip 简单易用。 先请看 \fpwebview-master\README.md cd \lazarus\projects\fpwebview-master\demo\lclembed 修改 lclembed.lpr 如下&#xff0c;将 fphttpapp. 注释掉&#xff0c;因为我用不上 a simple…

【RT-DETR有效改进】利用EMAttention加深网络深度提高模型特征提取能力(特征选择模块)

一、本文介绍 本文给大家带来的改进机制是EMAttention注意力机制,它的核心思想是,重塑部分通道到批次维度,并将通道维度分组为多个子特征,以保留每个通道的信息并减少计算开销。EMA模块通过编码全局信息来重新校准每个并行分支中的通道权重,并通过跨维度交互来捕获像素级…

Leetcode1686. 石子游戏 VI

Every day a Leetcode 题目来源&#xff1a;1686. 石子游戏 VI 解法1&#xff1a;贪心 排序 贪心的思想&#xff1a; 这道题模拟一个石子游戏&#xff0c;求解最后的比赛结果。 题目说两位玩家都会采用 最优策略 进行游戏&#xff0c;那么关键点就在于什么是最优策略&…

Swift Combine 合并多个管道以更新 UI 元素 从入门到精通十七

Combine 系列 Swift Combine 从入门到精通一Swift Combine 发布者订阅者操作者 从入门到精通二Swift Combine 管道 从入门到精通三Swift Combine 发布者publisher的生命周期 从入门到精通四Swift Combine 操作符operations和Subjects发布者的生命周期 从入门到精通五Swift Com…

Java 8中的Stream API是什么?

Java 8引入了一项强大的新抽象称为Stream API&#xff0c;旨在提高Java程序员在处理集合时的生产力。它是为了使集合的操作更加方便和高效&#xff0c;尤其是对于大数据集的处理。Stream API通过提供一种高级的、声明式编程方式来处理数据&#xff0c;允许对数据进行复杂的查询…

centos中docker操作+安装配置django+mysql5.7并使用simpleui美化管理后台

一、安装docker 确保系统是CentOS 7并且内核版本高于3.10,可以通过uname -r命令查看内核版本。 更新系统软件包到最新版本,可以使用命令yum update -y。 安装必要的软件包,包括yum-utils、device-mapper-persistent-data和lvm2。使用命令yum install -y yum-utils devic…

软考 系统分析师系列知识点之信息系统战略规划方法(11)

接前一篇文章&#xff1a;软考 系统分析师系列知识点之信息系统战略规划方法&#xff08;10&#xff09; 所属章节&#xff1a; 第7章. 企业信息化战略与实施 第4节. 信息系统战略规划方法 7.4.7 价值链分析法 价值链分析&#xff08;Value Chain Analysis&#xff0c;VCA&am…

.NET Core MongoDB数据仓储和工作单元模式封装

前言 上一章我们把系统所需要的MongoDB集合设计好了&#xff0c;这一章我们的主要任务是使用.NET Core应用程序连接MongoDB并且封装MongoDB数据仓储和工作单元模式&#xff0c;因为本章内容涵盖的有点多关于仓储和工作单元的使用就放到下一章节中讲解了。仓储模式&#xff08;R…

两年前的爱爱竟然让她染上菜花和梅毒!医师警告:性病潜伏期不可小觑,HPV疫苗是必备的

【记者许家源/综合报道】 台北市一名30多岁的女性&#xff0c;因为私密处长出不明物体&#xff0c;到泌尿科求诊&#xff0c;没想到被诊断出是菜花&#xff0c;而且还合并了梅毒。 她回想起自己最后一次发生性关系&#xff0c;竟然是两年前和前男友的事&#xff0c;不明白为什…

搭建 blender python api 的外部开发环境

以下都是为了不直接在 blender 的 script ide 里写脚本而做&#xff0c;直接在 blender 里写的话就没什么参考意义了。 首先是2个blender的设置选项&#xff0c;建议开启&#xff0c;会比较方便。 开发选项启用后&#xff0c;你在一些菜单上右键的话&#xff0c;会多出来 在线…

国内几个做的不错的研发效能度量工具

国内几个做的不错的研发效能度量工具&#xff1a; 1、PingCode https://sc.pingcode.com/uvo4u 2、思码逸 https://www.merico.cn 3 云效 https://www.aliyun.com/product/yunxiao/ 4、 Ones https://ones.cn/ 其中思码逸还是不错的&#xff0c;可以接入各种如禅道呀&a…

CleanMyMac X2024版本有哪些常见的使用场景?

CleanMyMac X作为一款Mac电脑清理和优化工具&#xff0c;具有多种使用场景。以下是一些常见的使用场景&#xff1a; 清理系统垃圾文件&#xff1a;CleanMyMac X可以智能扫描Mac磁盘空间&#xff0c;清理系统冗余文件和各种软件应用产生的垃圾文件&#xff0c;如缓存、日志文件…

Kotlin基础——类、对象和接口

文章目录 1 定义类继承结构1.1 接口1.1.1 接口概述1.1.2 接口中的默认方法1.1.3 接口方法重复1.1.4 Kotlin接口中静态方法实现原理 1.2 修饰符1.2.1 类继承修饰1.2.2 方法重写修饰1.2.3 抽象类1.2.4 接口的修饰符 1.3 可见性修饰符1.3.1 Kotlin中的可见性修饰符1.3.2 Kotlin中的…

记 proxifier

5EZ8G-C3WL5-B56YG-SCXM9-6QZAP

男人圣经 2

男人圣经&#x1f4d5; 2 强文喾哲改观制衡 功臣 强文 过去我学的思想都是真善美、好人就会有好报、有好名声等等。 真实世界其实是 强者才会有好报、世界上所有的好东西都是给强者准备的、世界法则就是奖励强者、惩罚弱者。 强者的根本属性是强势文化&#xff0c;和常人的思…