在阅读Rust Book的第12.4章时,我偶然发现了这个函数:
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
vec![]
}
我理解为什么如果没有contents
参数的显式生存期注释和返回值,代码就无法编译——生存期省略规则不适用于至少有两个借用参数的函数。
但我很好奇query
参数的隐式生存期注释是什么。我可以想到两种情况:
// Scenario 1
pub fn search<'a>(query: &'a str, contents: &'a str) -> Vec<&'a str> {
vec![]
}
// Scenario 2
pub fn search<'a, 'b>(query: &'b str, contents: &'a str) -> Vec<&'a str> {
vec![]
}
这两个场景都会编译,所以query
获得生存期'a
或'b
。哪一个是正确的?
从rustonomicon
,在寿命省略下:
输入位置中的每个消隐生存期都成为一个不同的生存期参数。
您可以尝试将函数分配给错误的类型。编译器会告诉您函数的正确类型:
let x: () = search;
游乐场
结果:
error[E0308]: mismatched types
--> src/main.rs:6:17
|
6 | let x: () = search;
| -- ^^^^^^ expected `()`, found fn item
| |
| expected due to this
|
= note: expected unit type `()`
found fn item `for<'r, 'a> fn(&'r str, &'a str) -> Vec<&'a str> {search}`
所以,你们的函数类型是:
for<'r, 'a> fn(&'r str, &'a str) -> Vec<&'a str> {search}
此外,如果query
也有寿命'a
,您应该能够做到这一点:
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
vec![query]
}
但由于query
的生存期不是'a
,因此无法编译。
游乐场
一种方法是,我们不是用生存期注释来"给定"生存期,而是描述返回值的生存期与输入的生存期之间的关系。
生命周期已经存在,但是注释允许我们设置它们之间的关系。由于在情况2中,您从未将query
的生存期与其他任何情况联系起来,因此我们不应该真的需要命名它。直观地说,这是最常见的情况,也是编译器在query
上不进行注释时应该(确实(推断的情况。