问题
In The Rust Programming Language, there is a chapter which implements a minigrep. Instead of implementing a second search_case_insensitive()
method, I wanted to implement a single API which would duplicate code. That attempt went something like this:
pub fn search<'a>(query: &str, lines: &'a str, case_insensitive: bool) -> Vec<&'a str> {
let mut results = Vec::new();
let mut query_to_search = query.clone();
if case_insensitive {
query_to_search = &query_to_search.to_lowercase();
}
for line in lines.lines() {
let mut line_to_search = line.clone();
if case_insensitive {
line_to_search = &line_to_search.to_lowercase();
}
if line_to_search.contains(&query_to_search) {
results.push(line);
}
}
return results;
}
This results in a compiler error:
error[E0597]: borrowed value does not live long enough
--> src/lib.rs:49:28
|
49| query_to_search = &query_to_search.to_lowercase();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value dropped here while still borrowed
| |
| temporary value does not live long enough
...
63| }
| - temporary value needs to live until here
|
= note: consider using a `let` binding to increase its lifetime
And there is a similar error for this line:
line_to_search = &line_to_search.to_lowercase();
I understand that to_lowercase()
is creating a new String
object which is going out of scope after the if-condition, which is causing the borrow checker to throw an error.
How can I extend the lifetime of the String
object returned by the to_lowercase()
method so that it's not freed without creating a duplicate objects to hold the lowercase versions of the query/lines objects?
EXAMPLE:
pub fn search<'a>(query: &str, lines: &'a str, case_insensitive: bool) -> Vec<&'a str> {
let mut results = Vec::new();
let query_lower_case = query.to_lowercase(); // We are retaining this lower case object unnecessarily for case sensitive search
let mut query_to_search: &str = &query.clone();
if case_insensitive {
query_to_search = &query_lower_case;
}
for line in lines.lines() {
let line_lower_case = line.to_lowercase(); // We are retaining this lower case object unnecessarily for case sensitive search
let mut line_to_search: &str = &line.clone();
if case_insensitive {
line_to_search = &line_lower_case;
}
if line_to_search.contains(&query_to_search) {
results.push(line);
}
}
return results;
}
来源:https://stackoverflow.com/questions/51332725/implementing-a-search-method-to-handle-optional-case-sensitivity