广潞 發表於 2025-2-26 09:36:20

使用环境变量实现Rust程序中的不区分大小写搜索方式

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>步骤 1:编写失败的测试</li><li>步骤 2:实现 search_case_insensitive 函数</li><li>步骤 3:修改 run 函数</li><li>步骤 4:获取环境变量</li><li>步骤 5:运行程序</li><li>总结</li></ul></div><p class="maodian"></p><h2>步骤 1:编写失败的测试</h2>
<p>我们遵循测试驱动开发(TDD)方法,首先编写一个测试来验证不区分大小写搜索功能。由于我们尚未实现该功能,因此这个测试会失败。</p>
<p>以下是测试代码:</p>
<div class="jb51code"><pre class="brush:bash;">#
mod tests {
    use super::*;

    // 测试:区分大小写的搜索
    #
    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));
    }

    // 测试:不区分大小写的搜索
    #
    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)
      );
    }
}</pre></div>
<p>在上述代码中:</p>
<ul><li><code>case_sensitive</code> 测试验证了原始的区分大小写的搜索。</li><li><code>case_insensitive</code> 测试验证了我们将在后面实现的不区分大小写的搜索。此时,由于我们还没有实现 <code>search_case_insensitive</code> 函数,编译将失败。</li></ul>
<p class="maodian"></p><h2>步骤 2:实现 search_case_insensitive 函数</h2>
<p>为了实现不区分大小写的搜索,我们需要修改 <code>search</code> 函数,使其能够忽略大小写。</p>
<p>以下是 <code>search_case_insensitive</code> 函数的实现:</p>
<div class="jb51code"><pre class="brush:bash;">// 不区分大小写的搜索函数
pub fn search_case_insensitive&lt;'a&gt;(
    query: &amp;str,       // 查询字符串
    contents: &amp;'a str, // 文件内容
) -&gt; Vec&lt;&amp;'a str&gt; {
    let query = query.to_lowercase(); // 将查询字符串转换为小写
    let mut results = Vec::new(); // 存储匹配结果

    // 遍历文件中的每一行
    for line in contents.lines() {
      // 将每一行转换为小写再进行比较
      if line.to_lowercase().contains(&amp;query) {
            results.push(line); // 如果匹配,加入结果列表
      }
    }

    results // 返回匹配的行
}</pre></div>
<p><strong>代码解释:</strong></p>
<ul><li><code>query.to_lowercase()</code> 将查询字符串转换为小写,以确保不区分大小写地进行匹配。</li><li><code>line.to_lowercase()</code> 将每一行内容转换为小写,并检查是否包含查询字符串。</li></ul>
<p class="maodian"></p><h2>步骤 3:修改 run 函数</h2>
<p><code>run</code> 函数是程序的核心,它负责执行搜索并输出结果。我们需要修改 <code>run</code> 函数,使其根据 <code>Config</code> 结构体中的 <code>ignore_case</code> 字段来决定是使用区分大小写的 <code>search</code> 函数,还是不区分大小写的 <code>search_case_insensitive</code> 函数。</p>
<div class="jb51code"><pre class="brush:bash;">// 根据配置运行搜索
pub fn run(config: Config) -&gt; Result&lt;(), Box&lt;dyn Error&gt;&gt; {
    let contents = fs::read_to_string(config.file_path)?; // 读取文件内容

    // 根据 ignore_case 字段决定使用哪种搜索
    let results = if config.ignore_case {
      search_case_insensitive(&amp;config.query, &amp;contents) // 不区分大小写的搜索
    } else {
      search(&amp;config.query, &amp;contents) // 区分大小写的搜索
    };

    // 打印匹配的行
    for line in results {
      println!("{line}");
    }

    Ok(())
}</pre></div>
<p><strong>代码解释:</strong></p>
<ul><li><code>Config</code> 结构体包含一个 <code>ignore_case</code> 字段,用于控制是否启用不区分大小写的搜索。</li><li>根据 <code>ignore_case</code> 的值,我们决定调用 <code>search</code> 还是 <code>search_case_insensitive</code>。</li></ul>
<p class="maodian"></p><h2>步骤 4:获取环境变量</h2>
<p>现在,我们需要从环境变量中获取 <code>IGNORE_CASE</code> 的值,来决定是否启用不区分大小写的搜索。</p>
<p>我们使用 Rust 标准库中的 <code>env</code> 模块来访问环境变量。</p>
<div class="jb51code"><pre class="brush:bash;">use std::env;

impl Config {
    // 构建 Config 实例
    pub fn build(args: &amp;) -&gt; Result&lt;Config, &amp;'static str&gt; {
      if args.len() &lt; 3 {
            return Err("not enough arguments");
      }

      let query = args.clone();
      let file_path = args.clone();

      // 检查环境变量 IGNORE_CASE 是否设置
      let ignore_case = env::var("IGNORE_CASE").is_ok(); // 如果环境变量存在,则启用不区分大小写的搜索

      Ok(Config {
            query,
            file_path,
            ignore_case,
      })
    }
}</pre></div>
<p><strong>代码解释:</strong></p>
<ul><li>我们使用 <code>env::var(&quot;IGNORE_CASE&quot;).is_ok()</code> 来检查环境变量 <code>IGNORE_CASE</code> 是否被设置。</li><li>如果设置了该环境变量,我们将 <code>ignore_case</code> 设置为 <code>true</code>,否则默认为 <code>false</code>。</li></ul>
<p class="maodian"></p><h2>步骤 5:运行程序</h2>
<p>现在,我们的程序已经支持根据环境变量来控制搜索模式。你可以通过以下命令来运行程序:</p>
<ol><li><strong>不使用环境变量,执行区分大小写的搜索:</strong></li></ol>
<div class="jb51code"><pre class="brush:bash;">$ cargo run -- to poem.txt</pre></div>
<ol start="2"><li><strong>设置环境变量 </strong><code>IGNORE_CASE=1</code><strong>,启用不区分大小写的搜索:</strong></li></ol>
<div class="jb51code"><pre class="brush:bash;">$ IGNORE_CASE=1 cargo run -- to poem.txt</pre></div>
<p>对于 PowerShell 用户,可以使用以下命令:</p>
<div class="jb51code"><pre class="brush:bash;">PS&gt; $Env:IGNORE_CASE=1; cargo run -- to poem.txt</pre></div>
<p class="maodian"></p><h2>总结</h2>
<p>通过使用环境变量,我们成功地在Rust程序中实现了不区分大小写的搜索功能。</p>
<p>这种方式让用户可以通过简单的环境变量配置来改变程序的行为,而不需要每次运行程序时都指定命令行参数。</p>
<p>通过这种方法,我们可以在命令行工具中灵活地控制不同的搜索模式,使程序更加友好和易于配置。</p>
<p><strong>在本教程中,我们:</strong></p>
<ul><li>通过 TDD 编写了失败的测试,并逐步实现了功能。</li><li>学会了如何使用 Rust 标准库中的 <code>env</code> 模块获取环境变量。</li><li>通过环境变量控制程序行为,让命令行工具更加灵活。</li></ul>
<p>通过这个示例,希望你对 Rust 中如何使用环境变量有所了解,并能够在自己的项目中灵活应用。</p>
<p>以上为个人经验,希望能给大家一个参考,也希望大家多多支持琼殿技术社区。</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>Rust生命周期之验证引用有效性与防止悬垂引用方式</li><li>如何使用Rust的向量存储值列表</li><li>Rust的泛型、Traits与生命周期用法及说明</li><li>使用cargo&nbsp;install安装Rust二进制工具过程</li><li>Rust如何使用线程同时运行代码</li><li>在Rust应用中访问.ini格式的配置文件方式</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: 使用环境变量实现Rust程序中的不区分大小写搜索方式