摘自《Rust编程语言》第13章第3节代码清单 13-29:
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
contents
.lines()
.filter(|line| line.contains(query))
.collect()
}
在上述内容的解释之后,读者被邀请“随意对search_case_insensitive
函数使用迭代器方法进行相同更改。” 我愿意这样做:
pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
contents
.lines()
.filter(|line| line.to_lowercase().contains(query.to_lowercase()))
.collect()
}
不行:
error[E0277]: expected a `FnMut<(char,)>` closure, found `String`
--> src/lib.rs:59:53
|
59 | .filter(|line| line.to_lowercase().contains(query.to_lowercase()))
| -------- ^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `Pattern<'_>`
| |
| required by a bound introduced by this call
|
= note: the trait bound `String: Pattern<'_>` is not satisfied
= note: required because of the requirements on the impl of `Pattern<'_>` for `String`
note: required by a bound in `core::str::<impl str>::contains`
help: consider borrowing here
|
59 | .filter(|line| line.to_lowercase().contains(&query.to_lowercase()))
| +
事实上,这段代码编译通过并且通过了之前示例的测试:
pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
contents
.lines()
.filter(|line| line.to_lowercase().contains(&query.to_lowercase()))
.collect()
}
事实上,如果query
是借用的,那么search
将会被编译并通过测试:
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
contents
.lines()
.filter(|line| line.contains(&query))
.collect()
}
那么为什么search_case_insensitive
函数必须借用query
参数,但对于search
函数来说,它是一个引用还是不是引用都没有影响呢?
query
在函数体中是一个String
,而在签名中声明为query: &str
。 - Franklin Einspruchquery
而是query.to_lowercase()
,并且str::to_lowercase()
返回的是String
。 - Chayim Friedman