为什么要借这个?
why should this be borrowed?
来自本书,listing 13-29:
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
contents
.lines()
.filter(|line| line.contains(query))
.collect()
}
在对上述内容进行解释后,邀请 reader,“请随意进行相同的更改以在 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()
}
那么为什么 query
必须在 search_case_insensitive
中借用,但它是(或不是)引用对 search
没有影响?
contains()
方法需要某种实现 Pattern
特性的类型作为输入。此特征是为 &str
实现的,而不是 String
。这意味着 contains()
可以与 &str
一起使用,但不能与 String
一起使用(至少不能直接使用)。
对于 line.contains(query)
的情况,query
已经是 &str
,所以我们很好。
query.to_lowercase()
returns 一个 String
类型,所以它不编译。但是,String
可以通过借用变成 &str
,这就是 &query.to_lowercase()
起作用的原因。
方法 str::contains()
takes as a predicate generic P: Pattern
. The Pattern
trait 已为 char
、&char
、&String
、&[char]
、&str
、&&str
实现、[char; N]
、&[char; N]
和 F where F: FnMut(char) -> bool
。所有这些都可以传递给 contains()
。但是,它没有为 String
实现。所以在 search()
中,你传递了 &str
。没关系。借了就传&&str
,也行。但是在 search_case_insensitive()
中,如果你借用你传递 &String
这很好,但如果你不借用,你传递 String
没有实现 Pattern
特性。
来自本书,listing 13-29:
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
contents
.lines()
.filter(|line| line.contains(query))
.collect()
}
在对上述内容进行解释后,邀请 reader,“请随意进行相同的更改以在 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()
}
那么为什么 query
必须在 search_case_insensitive
中借用,但它是(或不是)引用对 search
没有影响?
contains()
方法需要某种实现 Pattern
特性的类型作为输入。此特征是为 &str
实现的,而不是 String
。这意味着 contains()
可以与 &str
一起使用,但不能与 String
一起使用(至少不能直接使用)。
对于 line.contains(query)
的情况,query
已经是 &str
,所以我们很好。
query.to_lowercase()
returns 一个 String
类型,所以它不编译。但是,String
可以通过借用变成 &str
,这就是 &query.to_lowercase()
起作用的原因。
方法 str::contains()
takes as a predicate generic P: Pattern
. The Pattern
trait 已为 char
、&char
、&String
、&[char]
、&str
、&&str
实现、[char; N]
、&[char; N]
和 F where F: FnMut(char) -> bool
。所有这些都可以传递给 contains()
。但是,它没有为 String
实现。所以在 search()
中,你传递了 &str
。没关系。借了就传&&str
,也行。但是在 search_case_insensitive()
中,如果你借用你传递 &String
这很好,但如果你不借用,你传递 String
没有实现 Pattern
特性。