Rust - 从 `&str` 转换为 `String` 并使用闭包返回

问题描述

我正在处理 book,但我不明白为什么这个函数不能编译:

pub fn search<'a>(query: &str,contents: &'a str) -> Vec<&'a str> {
    contents
        .lines()                           // Fetch an iterator for each line in `contents`
        .map(|x| x.to_lowercase())         // (x is Now String) Convert each line to lowercase
        .filter(|x| x.contains(query))     // Filter out lines that do not contain query
        .map(|x| x.trim())                 // Eliminate extra whitespace
        .collect()                         // Consume iterator and produce Vec<&str>
}

如果没有 to_lowercase() 行,它将运行,我猜这是因为这将返回一个 String 而不是 &str 我们需要在最后输出。但是,当我将转换替换回 &str 时,例如:

// -- snip --
.map(|x| x.to_lowercase().to_str())
// -- snip --

这表明正在引用一个临时值。我认为这是因为 &str 引用了 String,当 String 发布时,它也会使我的 &str 无效。

闭包不是处理这个问题的好方法,我应该把它分解成不同的语句吗?

解决方法

这表明正在引用一个临时值。我认为这是因为 operator[] 引用了 &str,当 String 发布时,它也会使我的 String 无效。

这个假设是正确的。

闭包不是处理这个问题的好方法,我应该把它分解成不同的语句吗?

对该函数进行再多的重构都不会改变 &str 需要修改 to_lowercase() 并且必须生成 &str 的事实,因此如果需要将内容小写,那么这就是尽你所能:

String

如果你想执行不区分大小写的过滤但仍然返回未修改的内容(没有小写),那么你可以这样做:

fn search(query: &str,contents: &str) -> Vec<String> {
    contents
        .lines()                           // Fetch an iterator for each line in contents
        .map(|x| x.trim().to_lowercase())  // Trim & lowercase string
        .filter(|x| x.contains(query))     // Filter out lines that do not contain query
        .collect()                         // Consume iterator and produce Vec<String>
}
,

对于跟在我身后的人来说,这就是我结束的地方。谢谢@pretzelhammer。

pub fn search_case_insensitive<'a>(query: &str,contents: &'a str) -> Vec<&'a str> {
    let query = query.to_lowercase(); // transform query to lowercase()
    contents
        .lines() 
        .filter(|x| x.to_lowercase().contains(&query))
        .map(|x| x.trim())
        .collect()
}