【Rust学习】12. 项目实战-搜索关键词

参考:https://www.bilibili.com/video/BV1hp4y1k7SV
模仿grep写一个小项目

12.1 接受命令行参数

  1. 创建项目
cargo new minigrep
  1. 要在终端输入接受命令行参数,希望用户有如下输入
cargo run XXX XXXXX.txt
use std::env;
fn main() {
   
    let args:Vec<String>=env::args().collect();
    println!("{:?}",args);
}

输出

cargo run 
["target\\debug\\minigrep.exe"]
$ cargo run hello myfile.txt
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target\debug\minigrep.exe hello myfile.txt`
["target\\debug\\minigrep.exe", "hello", "myfile.txt"]

但是env::args0无法处理非法字符,会发生恐慌
TODO: 可以考虑用env::args_os()来解决,此处暂不考虑

  1. 接受两个参数并保存
use std::env;
fn main() {
   
    let args:Vec<String>=env::args().collect();
    println!("{:?}",args);
    let query =&args[1];
    let filename=&args[2];
    println!("Search for '{}'",query);
    println!("In file {}",filename);
}
$ cargo run hello myfile.txt
   Compiling minigrep v0.1.0 (D:\Workplace\Rust\study\minigrep)
    Finished dev [unoptimized + debuginfo] target(s) in 0.14s
     Running `target\debug\minigrep.exe hello myfile.txt`
["target\\debug\\minigrep.exe", "hello", "myfile.txt"]
Search for 'hello'
In file myfile.txt

12.2 读取文件

use std::env;
use std::fs;//处理和文件相关的任务
fn main() {
   
    let args:Vec<String>=env::args().collect();
    let query =&args[1];
    let filename=&args[2];

    println!("Search for '{}'",query);
    println!("In file {}",filename);

    let contents=fs::read_to_string(filename)
    .expect("Someing went wrong reading the file");

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

$ cargo run abc story.txt
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target\debug\minigrep.exe abc story.txt`
Search for 'abc'
In file story.txt
With text:
Working from home has become increasingly common, but it can be a challenge to stay productive in this environment.
To maintain focus, it is important to establish a designated workspace that is free of distractions.
It is also helpful to set specific work hours and take regular breaks throughout the day to stay energized.
Minimizing distractions such as social media notifications or TV shows can help increase productivity.
Finally, staying connected with colleagues through video conferencing tools can prevent feelings of isolation.
By implementing these tips, individuals can stay productive while working from home and maintain a healthy work-life balance.

12.3 重构:改进模块

存在问题:

  • 主函数负责的任务太多了
  • 程序代码最好一个函数负责一个功能
  • 字段太多太杂难以管理–创建struct管理
  • 错误打印的信息不清晰错误处理不好,难以维护,放置一处处理好

二进制程序关注点分离的指导性原则

  • 将程序拆分为 main.rs 和 librs,将业务逻辑放入 lib.rs
  • 当命令行解析逻辑较少时,将它放在main.rs也ok
  • 当命令行解析逻辑变复杂时,需要将它从 main.rs 提取到lib.rs
    main负责运行
    lib负责处理业务逻辑

经过上述拆分,留在 main 的功能有:

  • 使用参数值调用命令行解析逻辑
  • 进行其它配置
  • 调用lib.rs中的run函数
  • 处理run函数可能出现的错误
fn main() {
   
    let args:Vec<String>=env::args().collect();
    
    let (query,filename)=parse_config(&args);
...
}
fn parse_config(args:&[String])->(&str,&str){
   
    let query=&args[1];
    let filename=&args[2];
    (query,filename)
}

但是两个配置参数放在一个元组里,没有关联
-----放在一个struct里面

use std::env;
use std::fs;//处理和文件相关的任务
fn main() {
   
    let args:Vec<String>=env::args().collect();

    let config=parse_config(&args);
    let contents=fs::read_to_string(config.filename)
    .expect("Someing went wrong reading the file");

    println!("With text:\n{}",contents);
}
struct Config{
   
    query:String,
    filename:String,
}
fn parse_config(args:&[String])->Config{
   
    let query=args[1].clone();
    let filename=args[2].clone();
    Config {
    query, filename }
}

clone虽然低效,但是简洁性强
把函数和config相关联

use std::env;
use std::fs;//处理和文件相关的任务
fn main() {
   
    let args:Vec<String>=env::args().collect();

    let config=Config::new(&args);
    let contents=fs::read_to_string(config.filename)
    .expect("Someing went wrong reading the file");

    println!("With text:\n{}",contents);
}
struct Config{
   
    query:String,
    filename:String,
}
impl Config{
   
    fn new (args:&[String])->Config{
   
        let query=args[1].clone();
        let filename=args[</
<think>好的,我现在需要帮用户解决“新手编程学习思路”的问题。首先,我得想想用户可能的需求是什么。用户是编程新手,所以需要从最基础的开始,逐步引导他们。可能需要先确定学习目标,然后选择合适的语言,接着是基础语法,再到项目实践,最后是持续提升。 用户可能没有明确的方向,不知道该从哪里下手。所以第一步应该建议他们明确目标,比如开发网站、做数据分析或者游戏开发。不同的目标对应不同的语言选择,比如Python适合数据分析,JavaScript适合网页开发。这点很重要,因为选择适合的语言能增加学习的动力。 接下来是学习编程基础。变量、数据类型、控制结构这些是必须的,但新手可能会觉得枯燥。需要强调循序渐进,避免一开始就接触复杂的概念,比如面向对象或者设计模式。同时,要提醒他们注意代码规范,比如命名规范和注释,这对以后协作和可读性很重要。 然后是项目实践。新手可能不知道如何将所学应用到实际中,应该鼓励他们从小项目开始,比如计算器或待办事项列表,这样可以巩固知识。同时,参与开源项目或团队协作也是提升的好方法,但可能需要一定的引导。 遇到问题怎么办?调试和解决问题是关键能力。要教会他们使用搜索引擎、官方文档和社区资源,比如Stack Overflow。调试工具的使用也是需要练习的,比如断点和日志输出。 持续学习方面,推荐书籍和在线课程,但要选择适合新手的资源。参与技术社区可以保持学习热情,了解行业动态。算法和数据结构是进阶的基础,但可能需要一定的编程基础后再深入。 最后,要提醒避免常见的误区,比如不要追求完美代码,不要死记硬背,也不要过早接触复杂领域。保持耐心和坚持是关键。 现在要确保结构清晰,分点说明,使用用户易懂的语言。同时,按照系统指令,数学公式用$...$,独立公式用$$...$$,不过这个问题可能涉及数学较少,但如果有例子的话需要注意格式。比如在讲解算法复杂度时可能会提到$O(n)$,这时要用正确的格式。 检查是否有LaTeX语法错误,确保中文回答,不使用Markdown格式。最后,总结整个思路,让用户有一个明确的路径,从目标到实践,再到提升,逐步成长。</think>编程新手学习可遵循以下分阶思路(附知识地图): 一、明确学习目标(先导阶段) $$学习方向 = \begin{cases} Web开发 \rightarrow JavaScript/Python \\ 移动开发 \rightarrow Kotlin/Swift \\ 数据分析 \rightarrow Python/R \\ 游戏开发 \rightarrow C#/C++ \\ 系统编程 \rightarrow Go/Rust \end{cases}$$ 建议优先选择Python或JavaScript作为入门语言,因其语法简洁且应用场景广泛 二、掌握编程基础(筑基阶段) 1. 核心语法三要素: - 变量与数据类型:理解$变量 = 存储容器 + 类型标识$ - 控制结构:掌握条件语句(if-else)、循环语句(for/while) - 函数机制:理解$输出 = f(输入)$的映射关系 2. 代码规范训练: - 命名规范:userCount优于a - 注释规范:关键逻辑需添加说明 - 缩进规则:严格遵循语言约定 三、项目实践驱动(实战阶段) 推荐实践路线: ``` 命令行工具 → 简单网页 → 数据库应用 → API开发 → 完整项目 ``` 典型入门项目- 温度单位转换器(变量运用) - 质数判断程序(循环逻辑) - 待办事项管理系统(CRUD操作) 四、调试与问题解决(关键能力) 1. 错误处理三部曲: 1. 阅读错误信息:定位报错位置 2. 最小化复现:构造简单测试用例 3. 分层验证:使用print/debugger逐层排查 2. 资源利用策略: - 官方文档 > 技术博客 > 视频教程 - Stack Overflow搜索技巧:使用[标签]+关键词 五、持续提升路径(进阶阶段) 1. 计算机科学基础: - 算法复杂度分析(理解$O(n)$等表示法) - 数据结构:掌握链表、栈、队列的实现 $$二叉树深度 = \max(左子树深度, 右子树深度) + 1$$ 2. 工程化能力培养: - 版本控制(Git基础) - 单元测试编写 - 持续集成概念 六、避坑指南 1. 避免过早深入: - 设计模式 - 框架源码 - 系统架构 2. 克服典型障碍: - "教程地狱":看3小时教程不如写30分钟代码 - "完美主义":先实现再优化 - "知识焦虑":建立个人知识图谱 建议每周保持10小时有效学习,3个月后可完成从0到1的跨越。关键路径:基础语法(2周)→小程序开发(4周)→完整项目(6周)→迭代优化(持续)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值