学习Rust的第29天: cat in Rust

今天即将是这个系列的最后一次内容,我们正在catRust 中从 GNU 核心实用程序进行重建。cat用于将文件内容打印到STDOUT.听起来很容易构建,所以让我们开始吧。

GitHub 存储库:GitHub - shafinmurani/gnu-core-utils-rust

伪代码

function read(path)->result{read contents of pathpropogate any errors to the caller
}args = command_line_arguments
remove the first element of the args vectorif args.length == 0 {print error_message
}
else if args.contains("--help") {print help_message
} else {for path in args {result = remove(path);error handling}
}

设置任务

正如我们往常所做的那样,让我们impl​​在库箱中创建一个结构体和一个块。

pub struct Config<'a> {file_names: &'a Vec<String>,
}impl Config<'_> {pub fn new(args: &Vec<String>){Config{ file_names: args }}fn not_enough_arguments(){eprintln!("cat: missing operand");eprintln!("for help: cat --help");}fn help(){eprintln!("Welcome to cat in Rust, This is a a little copy of the cat utility present in the GNU core utilities. I made this to practice my rust skills. Check out my articles at https://shafinmurani.medium.com");eprintln!("To use: cat file_name1 file_name2 file_name3");}fn read_documents(){}pub fn run(&self){if self.file_names.len() == 0 {Self::not_enough_arguments();} else if self.file_names.contain(&String::from("--help")){Self::help();} else {//We call the read_documents function here}}
}
  • 该代码定义了一个Config带有生命周期参数的结构体'a,其中包含一个file_names对字符串向量的引用的字段。
  • Config结构有一个关联的实现块 ( impl),用于与 相关的方法Config
  • new方法是 的构造函数Config,将对字符串向量的引用args作为输入,并返回一个设置为 的Config实例。file_namesargs
  • not_enough_arguments方法向 stderr 打印一条错误消息,指示该cat命令缺少操作数,建议使用cat --help.
  • help方法打印欢迎消息和cat命令的使用说明。
  • read_documents方法当前留空,可能会被实现来读取和打印指定文件的内容。
  • run方法是执行命令的主要函数cat
  • 它首先检查是否没有提供文件名,在这种情况下它调用not_enough_arguments.
  • 然后它检查--help文件名中是否存在该标志,如果存在,则调用该help方法。
  • 否则,假设提供了文件名,并且它将继续读取和打印这些文件的内容,当前将其作为注释保留。

read_documents() 方法

我们将向此函数传递一个文件路径,它将输出文件的内容,为此,我们使用以下内容:

  1. std::fs::File: 打开文件
  2. std::io::Read:将内容读取到字符串变量

让我们导入这些东西并编写read_document()函数并使用它

use std::fs::File;
use std::io::Read;pub struct Config<'a> {file_names: &'a Vec<String>,
}impl Config<'_> {pub fn new(args: &Vec<String>){Config{ file_names: args }}fn not_enough_arguments(){eprintln!("cat: missing operand");eprintln!("for help: cat --help");}fn help(){eprintln!("Welcome to cat in Rust, This is a a little copy of the cat utility present in the GNU core utilities. I made this to practice my rust skills. Check out my articles at https://shafinmurani.medium.com");eprintln!("To use: cat file_name1 file_name2 file_name3");}fn read_documents(file: String) -> std::io::Result<String>{let mut file_buffer = File::open(file)?;let mut file_content = String::new();file_buffer.read_to_string(&mut file_content)?;Ok(file_content)}pub fn run(&self){if self.file_names.len() == 0 {Self::not_enough_arguments();} else if self.file_names.contain(&String::from("--help")){Self::help();} else {for file in self.file_names {let result = Self::read_document(file.to_string());match result {Ok(data) => println!("{}",data),Err(e) => eprintln!("Application Error: `{}` {}", file, e),};}}}
}

现在这一切都完成了,我们可以处理我们的二进制箱并专注于运行它......

二进制箱

这里的逻辑很简单

  1. 导入Config结构体
  2. 获取命令行参数
  3. 删除第一个参数
  4. 实例化配置
  5. 配置.run()

让我们实践并运行它。

use cat::Config;
use std::env;fn main(){let mut args: Vec<String> = env::args().collect();args.remove(0);let config = Config::new(args);config.run();
}

运行它

cat我们将使用该工具来阅读我们工具的源代码cat。谈论 Catception 💀

# ./cat lib.rsuse std::fs::File;
use std::io::Read;pub struct Config<'a>{file_names: &'a Vec<String>,
}impl Config<'_>{pub fn new(args: &Vec<String>) -> Config{Config{ file_names: args }}fn help(){eprintln!("Welcome to cat in Rust, This is a little copy of the cat utility present in the GNU core utilities. I made this to practice my rust skills. Check out my articles at https://shafinmurani.medium.com");eprintln!("To use: cat file_name1 file_name2 ... file_nameN");}fn not_enough_arguments(){eprintln!("cat: missing operand");eprintln!("for help: cat --help");}fn read_document(file: String) -> std::io::Result<String>{let mut file_buffer = File::open(file)?;let mut file_content = String::new();file_buffer.read_to_string(&mut file_content)?;Ok(file_content)}pub fn run(&self){if self.file_names.len() == 0 {Self::not_enough_arguments();} else if self.file_names.contains(&String::from("--help")) {Self::help();} else {for file in self.file_names {let result = Self::read_document(file.to_string());match result {Ok(r) => println!("{}",r),Err(e) => eprintln!("Application Error: `{}` {}",file,e)};}}}
}

结论

库文件

  • lib.rs文件定义了 crate 的主要功能cat
  • 它从标准库(std::fs::Filestd::io::Read)导入必要的模块以进行文件处理。
  • 它声明了一个Config带有生命周期参数的结构体'a,其中包含一个file_names对字符串向量的引用的字段。
  • impl与 相关的方法有一个实现块 ( ) Config
  • new方法是 的构造函数Config,将对字符串向量的引用args作为输入,并返回一个设置为 的Config实例。file_namesargs
  • help方法打印欢迎消息和cat命令的使用说明。
  • not_enough_arguments方法向 stderr 打印一条错误消息,指示该cat命令缺少操作数,建议使用cat --help.
  • read_document方法读取由名称指定的文件的内容并将其作为 a 返回String,处理潜在的 IO 错误。
  • run方法是执行命令的主要函数cat
  • 它检查是否没有提供文件名,在这种情况下它调用not_enough_arguments.
  • 然后它检查--help文件名中是否存在该标志,如果存在,则调用该help方法。
  • 否则,它会迭代每个文件名,使用 读取其内容read_document,并将其打印到标准输出。

主程序.rs

  • main.rs文件充当可执行文件的入口点。
  • 它从板条箱Config中导入结构catenv从标准库中导入模块。
  • main函数将命令行参数收集到字符串向量中,删除第一个参数(程序名称本身),然后Config使用剩余参数创建一个实例Config::new
  • 最后,它调用实例run上的方法Config来执行cat命令。

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

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

相关文章

省公派出国|社科类普通高校教师限期内赴英国访学交流

在国外访问学者申请中&#xff0c;人文社科类相对难度更大&#xff0c;尤其是英语语言学&#xff0c;作为非母语研究并不被国外高校看重。经过努力&#xff0c;最终我们帮助Z老师申请到英国坎特伯雷基督教会大学的访学职位&#xff0c;并在限期内出国。 Z老师背景&#xff1a; …

TypeScript学习日志-第二十天(模块解析)

模块解析 一、ES6之前的模块规范 前端模块化规范是有很多的&#xff0c;在es6模块化规范之前分别有一下的模块化规范 一、Commonjs 这是 NodeJs 里面的模块化规范 // 导入 require("xxx"); require("../xxx.js"); // 导出 exports.xxxxxx function() …

Java 【数据结构】常见排序算法实用详解(上) 插入排序/希尔排序/选择排序/堆排序【贤者的庇护】

登神长阶 上古神器-常见排序算法 插入排序/选择排序/堆排序 &#x1f4d4; 一.排序算法 &#x1f4d5;1.排序的概念 排序 &#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&a…

数据结构===树

文章目录 概要概念相关概念 有哪些常用的树小结 概要 树是一种新的数据结构&#xff0c;不同于数组&#xff0c;链表。就像大自然中的树&#xff0c;看下这个数据结构&#xff0c;很有意思&#xff0c;有一个主干&#xff0c;然后还有很多树叉&#xff0c;即支干。不错&#xf…

微信视频号如何变现呢,视频号涨粉最快方法

今天给大家带来的是视频号分成计划 视频号流量主这个项目&#xff0c;可以说这是目前的一个蓝海赛道&#xff0c;做的人也少&#xff0c;外面开的培训也很少&#xff0c;作为副业还是比较适合个人的&#xff0c;如果想批量操作这个项目&#xff0c;也比较适合工作室的。而且这…

51-48 CVPR 2024 | Vlogger: make your dream a vlog 自编剧制作视频博客

24年1月&#xff0c;上海交大、上海人工智能实验室、中科院联合发布Vlogger&#xff1a;make your dream a vlog。该论文主要工作是生成超过5分钟的视频博客vlog。鉴于现有文本到视频T2V生成方法很难处理复杂的故事情节和多样化的场景&#xff0c;本文提出了一个名为Vlogger的通…

Ansible的安装与基础命令的使用

Ansible Ansible 是一个开源的自动化工具&#xff0c;用于配置管理、应用部署和任务自动化。它由 Michael DeHaan 于 2012 年创建&#xff0c;后来被 Red Hat 收购。Ansible 的设计理念是简单易用&#xff0c;不需要在受管节点上安装任何代理软件&#xff0c;它通过 SSH&#…

-LAW5556

1 SCHOOL OF LAW Module Code: LAW5556 Module title: Corporate Finance and Securities Law Provisional Assessed Essay – Semester 2 – 2023-2024 Submission Date: Thursday 6 th June 2024 Word Limit: 3,000 INSTRUCTIONS 1. The assessment will count for 1…

WINDOWS配置IIS

1.安装IIS 1.1.打开启用Windows功能 打开“控制面板” > “程序和功能” > “启用或关闭 Windows 功能”。 1.2.启用IIS功能 打开“控制面板” > “程序和功能” > “启用或关闭 Windows 功能”。 勾选“Internet Information Services”&#xff0c;然后点击“确定…

vs配置cplex12.10

1.创建c空项目 2.修改运行环境 为release以及x64 3.创建cpp文件 4.鼠标右键点击项目中的属性 5.点击c/c&#xff0c;点击第一项常规&#xff0c;配置附加库目录 5.添加文件索引&#xff0c;主要用于把路径导进来 6.这一步要添加的目录与你安装的cplex的目录有关系 F:\program…

NFS共享存储服务配置实践

一、NFS 1.NFS定义 NFS&#xff08;Network File System&#xff09;网络文件服务&#xff1a;基于TCP/IP传输的网络文件系统协议&#xff0c;NFS服务的实现依赖于RPC&#xff08;Remote Process Call&#xff09;远端过程调用&#xff1a;通过使用NFS协议&#xff0c;客户机…

【HDFS】 双Buffer数据结构:EditsDoubleBuffer

缓冲(Buffer)机制是对数据持久化的延迟,以减少不必要的IO,从而提高数据落盘的效率。 一般需要使用双缓冲区的地方都是由于“生产者”和“消费者”供需不一致所造成的。 两个缓冲区可以交换,互相变成对方的角色。 HDFS引入双Buffer的背景及带来的收益 每次客户端的RPC请求…

机器学习——3.梯度计算与梯度下降

基本概念 梯度的本意是一个向量&#xff08;矢量&#xff09;&#xff0c;表示某一函数在该点处的方向导数沿着该方向取得最大值&#xff0c;即函数在该点处沿着该方向&#xff08;此梯度的方向&#xff09;变化最快&#xff0c;变化率最大&#xff08;为该梯度的模&#xff0…

404 Not Found - GET https://registry.npmjs.org/fs-promises

具体错误 npm install fs-promises npm ERR! code E404 npm ERR! 404 Not Found - GET https://registry.npmjs.org/fs-promises - Not found npm ERR! 404 npm ERR! 404 fs-promises* is not in this registry. npm ERR! 404 You should bug the author to publish it (or …

Vue、React实现excel导出功能(三种实现方式保姆级讲解)

第一种&#xff1a;后端返回文件流&#xff0c;前端转换并导出&#xff08;常用&#xff0c;通常公司都是用这种方式&#xff09; 第二种&#xff1a;纯后端导出&#xff08;需要了解&#xff09; 第三种&#xff1a;纯前端导出&#xff08;不建议使用&#xff0c;数据处理放…

rocky9 安装docker

一&#xff0c;Docker简介 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的Linux机器上&#xff0c;也可以实现虚拟化&#xff0c;容器是完全使用沙箱机制&#xff0c;相互之间不会有…

算法竞赛——从C/C++到Java

一、基础语法部分&#xff08;请自行复习相关语法&#xff09; 1.1 数组的定义 1.2 输入输出方式&#xff08;必要时需要快读和快写&#xff09; 二、Java中模拟结构体数组的实现方案 public class Main {public static void main(String[] args) {// TODO Auto-generated m…

Apache RabbitMQ 的所有组件以及他是如何保证顺序消费消息的

一、Apache RabbitMQ定义 Apache RabbitMQ 是一个开源消息队列系统&#xff0c;基于 Erlang 语言开发&#xff0c;实现了高级消息队列协议&#xff08;AMQP&#xff09;。RabbitMQ 提供了多种消息传递机制&#xff0c;包括点对点&#xff08;direct&#xff09;、发布/订阅&am…

mybatis配置获取自增主键

mybatis配置获取自增主键 【/n】 01 使用场景 当需要刚刚插入数据库的数据对应的新增主键时&#xff0c;通过配置xml文件&#xff0c;使数据库返回新增主键id&#xff0c;并把主键id与类参数对应 02 涉及配置 注解TableId(type IdType.AUTO)&#xff1a;在类主键id通过配…

【CTF MISC】XCTF GFSJ0512 give_you_flag Writeup(图像处理+QR Code识别)

give_you_flag 菜狗找到了文件中的彩蛋很开心&#xff0c;给菜猫发了个表情包 解法 图片的最后一帧好像闪过了什么东西。 用 Photoshop 打开&#xff0c;检查时间轴。 找到一张二维码&#xff0c;但是缺了三个角&#xff08;定位图案&#xff09;&#xff0c;无法识别。 找一…