【发布时间】:2018-07-04 06:10:31
【问题描述】:
我在chapter 12 of The Rust Programming Language,实现了不区分大小写的行搜索。两次实现相同的逻辑对我来说没有意义,所以我想如果我只是调用区分大小写的搜索函数并将参数转换为小写,那可能会起作用。它没。
这是我的非工作代码:
fn main() {
let a = search("Waldo", "where in\nthe world\nis Waldo?");
let b = search("waldo", "where in\nthe world\nis Waldo?");
let c = search_case_insensitive("waldo", "where in\nthe world\nis Waldo?");
println!("{:?}", a);
println!("{:?}", b);
println!("{:?}", c);
}
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
let mut results = Vec::new();
for line in contents.lines() {
if line.contains(query) {
results.push(line);
}
}
results
}
pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
let query = query.to_lowercase();
let contents2: &str = &contents.to_lowercase();
search(&query, contents2)
}
我提出的大多数版本中的错误不可避免地非常类似于:
error[E0597]: borrowed value does not live long enough
--> src/main.rs:25:28
|
25 | let contents2: &str = &contents.to_lowercase();
| ^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough
...
28 | }
| - temporary value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 23:1...
--> src/main.rs:23:1
|
23 | pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
【问题讨论】:
-
嗨!您能否解释一下您不理解错误消息的哪一部分?你对此有什么困惑?谢谢!
-
@LukasKalbertodt 并不是我不理解这个错误。显然 to_lowercase() 返回一个新字符串,因为具有翻转大小写的 unicode 字符串可能具有与原始字符串不同的长度。这个新字符串必须在函数结束时释放。然而,返回值使用了这个新字符串的一部分,这就是导致错误的原因。我不明白的是如何解决它。
-
为什么
&'a str换成contents2? -
@ljedrz 同样的原因我什至有一个内容2,我或多或少地随机尝试了一些东西,希望让错误消失。添加生命周期参数就是其中之一。删除它并不会真正改变错误。仅将其更改为 'b 会更改错误。但我需要做的是想办法让字符串比函数更有效(我不知道强制借用)或重构,所以这不再是问题了,但我有点迷茫
-
@Shepmaster 我已编辑问题以添加最少、完整的代码。您可以验证它是否会产生相同的错误。如果将函数的返回类型替换为 Vec
并将 String::from(line) 推送到向量中,它也可以按预期编译和工作,而不仅仅是 line。我想这是我一直在寻找的解决方案,尽管也许有更好的方法。在这个例子中,有人可能会争辩说,Simon Whitehead 的功能不一样,两个函数都应该有一个循环,但我希望能找到一种灵丹妙药。可能是我太乐观了
标签: string rust borrow-checker