我是rust的新手,我正在构建grep命令的实现来学习这门语言。我试图创建一个函数来以不区分大小写的方式匹配搜索查询,但我在处理for循环中str.lines()
迭代器返回值的生命周期时遇到了麻烦。
这是一个包含我正在实现的函数的最小可重复示例:
use grep::{run, Config};
use std::{env::args, process};
pub struct Config {
file_path: String,
query: String,
}
fn main() {
let contents: Config =Config {query: "Hello world!".to_owned(), file_path: "test".to_owned()};
let matches = search_case_sensitive(&config, &contents);
print_matches(&matches);
Ok(config)
}
type Match<'a> = Vec<(&'a str, &'a str, &'a str)>;
// this function causes the compile error
// contents -> the full text content of the file i previously read
// config.query -> the string i'm searching for inside contents
fn search_case_insensitive<'a>(config: &Config, contents: &'a str) -> Match<'a> {
let mut matches: Match<'a> = Vec::new();
let query = config.query.to_lowercase();
for line in contents.lines() {
let indexes = line.to_lowercase().match_indices(&query);
for (i, found) in indexes {
let prev = &line[..i];
let next = &line[i + found.len()..];
matches.push((prev, found, next));
}
}
matches
}
字符串
编译时会出现这个错误:
error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:34:23
|
34 | let indexes = line.to_lowercase().match_indices(&query);
| ^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary value which is freed while still in use
35 | for (i, found) in indexes {
| ------- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
型
据我所知,line
应该被绑定到'a
的生存期,因为它是对contents
的每个元素的引用,但这并没有发生,所以line
不是借用的,而是移动的,i的生存期不足以在indexes
中使用。
如何从contents中借用line并将其绑定到'a
生存期?
1条答案
按热度按时间rryofs0p1#
问题是
line.to_lowercase()
是函数的本地值,但你返回了它。最简单的解决方法是创建一个owned
String
:字符串
但是,请注意,您的代码仍然是不正确的。具体来说,
to_lowercase()
可以更改字符索引,甚至在一般情况下lowercasing two strings and comparing them is not enough for a case-insensitive comparison with respect to Unicode。