You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust大小写不敏感搜索函数报E0716错误,如何正确复用search函数?

Let's break down what's going wrong here, and fix both the lifecycle error and the hidden logical issue in your code.

First, let's recap your setup: you have a working case-sensitive search function that returns references to lines from the original contents string:

pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    let mut matching_lines: Vec<&str> = Vec::new();
    for line in contents.lines() {
        if line.contains(query) {
            matching_lines.push(line);
        }
    }

    matching_lines
}

You tried to reuse this for case-insensitive search by converting inputs to lowercase, but hit this error:

error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:25:17
|
25 | let query = query.to_lowercase().as_str();
| ^^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary which is freed while still in use
26 | let contents_lower = contents.to_lowercase().as_str();
27 | search(query, contents_lower)
| ----- borrow later used here

Why This Happens

The to_lowercase() method returns a new String (it has to, since modifying case changes the string data). When you call as_str() on that result, you get a reference to this temporary String—but the temporary is destroyed as soon as the line ends. By the time you call search, those references are pointing to freed memory, which Rust's borrow checker correctly blocks.

On top of that, even if the lifecycle error didn't exist, your approach has a logical flaw: converting the entire contents to lowercase and passing that to search would return references to the lowercase copy, not the original lines from contents—which is almost certainly not what you want.

The Fixes

Option 1: Implement Case-Insensitive Search Directly (Minimal Duplication)

Instead of trying to reuse the original search function directly, we can replicate its logic but add case-insensitive matching, while still returning references to the original lines:

pub fn insensitive_search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    let query_lower = query.to_lowercase();
    contents.lines()
        .filter(|line| line.to_lowercase().contains(&query_lower))
        .collect()
}

Here, we:

  1. Pre-convert the query to lowercase once (more efficient than doing it per line)
  2. Iterate over the original lines from contents
  3. Convert each line to lowercase only for the match check
  4. Collect and return references to the original lines (preserving the 'a lifecycle)

Option 2: Refactor search to Be Generic (Full Code Reuse)

If you want to avoid duplicating the line-iteration logic entirely, refactor search to accept a matching closure. This makes it flexible enough to handle both case-sensitive and case-insensitive searches:

// Generic search function that takes a matcher closure
pub fn search<'a, F>(contents: &'a str, matcher: F) -> Vec<&'a str>
where
    F: Fn(&str) -> bool,
{
    contents.lines()
        .filter(matcher)
        .collect()
}

// Case-sensitive search (uses the generic function)
pub fn sensitive_search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    search(contents, |line| line.contains(query))
}

// Case-insensitive search (also uses the generic function)
pub fn insensitive_search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    let query_lower = query.to_lowercase();
    search(contents, |line| line.to_lowercase().contains(&query_lower))
}

This way, you only write the line-iteration and collection logic once, and reuse it for both search types.

Key Takeaways

  • Rust's borrow checker prevents dangling references, which is why your original code failed—temporary Strings can't be referenced after they're destroyed.
  • When you need to return references to the original input data, avoid converting the entire input to a new string (like contents.to_lowercase()) because references to that new string won't match the original's lifecycle.
  • Using closures is a great way to make functions generic over behavior without duplicating code.

内容的提问来源于stack exchange,提问作者JudasMoses

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 16:56:15