rust 转换为小写后返回str的向量

v64noz0r  于 2023-01-30  发布在  其他
关注(0)|答案(2)|浏览(200)

我从Rust编程书中有一个搜索函数,可以搜索与模式匹配的行(查询)。

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
}

在书中,它几乎重写了完全相同的代码来搜索相同的东西但忽略了大写字母,我想通过调用带小写参数的函数来重用相同的代码会更有效率。

pub fn insensitive_search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    let query = query.to_lowercase().as_str();
    let contents_lower = contents.to_lowercase().as_str();
    search(query, contents_lower)
}

这将产生以下错误

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
   |

我知道这会导致错误,因为to_lowercase函数获得所有权,我不能从函数返回它,因为它将在函数返回后被清除,这意味着它是无效数据。
我怎样才能重写它使它有效呢?在这里使用String是否更好?

mwg9r5ms

mwg9r5ms1#

我知道这会导致错误,因为to_lowercase函数取得了所有权
它不会这样做,但它确实创建了源代码的副本,以便将其小写。
我怎样重写它才能使它有效?
你不能,因为数据属于当前函数,返回引用向量的唯一方法是如果父函数传入一个可变缓冲区,你可以在其中写入小写数据,然后你可以对 * 那个 * 进行切片,但这对于需要来说是一个巨大的复杂性。
在本例中使用String是否更好?
是的,因为这是lowercase()返回的值。
在其他情况下,您可以使用Cow来避免为新的所有权“付费”,但在这里,这会增加相当多的复杂性,并且(取决于字符串的长度以及已经小写与需要小写的比率)您甚至可能无法补偿条件检查:对于每一个输入字符串,你需要检查它是否已经是小写的,如果是,你可以返回原始字符串的Cow::Borrowed,否则你返回小写字符串的Cow::Owned

yws3nbqq

yws3nbqq2#

如果只使用ASCII字符串,则以下解决方案有效:

pub fn insensitive_search<'a>(query: &'a mut str, contents: &'a mut str) -> Vec<&'a str> {
    query.make_ascii_lowercase();
    contents.make_ascii_lowercase();
    search(query, contents)
}

字符串将在适当的位置更改为它们的小写等效项。

相关问题