当第二个参数用 'a 注释时,第一个参数的隐式生命周期是多少?
What is the implicit lifetime for the 1st argument when the 2nd argument is annotated with 'a?
在阅读 Rust Book Chapter 12.4 时,我偶然发现了这个函数:
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
vec![]
}
我理解为什么代码在没有 contents
参数和 return 值的显式生命周期注释的情况下无法编译 - lifetime elision rules 不适用于至少两个借用的论点。
但我很好奇 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
,在 lifetime elision 下:
Each elided lifetime in input position becomes a distinct lifetime parameter.
您可以尝试将函数分配给错误的类型。编译器会告诉你函数的正确类型:
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
。
一种思考方式是,我们不是 'giving' 带有生命周期注释的生命周期,而是描述 return 值的生命周期如何与输入的生命周期相关。
生命周期已经存在,但是注释让我们可以设置它们之间的关系。由于您永远不会将 query
的生命周期与情况 2 中的任何其他内容相关联,因此我们真的不需要命名它。直观地说,这是最常见的情况,如果您没有对 query
.
进行注释,编译器应该(确实)推断出这种情况
在阅读 Rust Book Chapter 12.4 时,我偶然发现了这个函数:
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
vec![]
}
我理解为什么代码在没有 contents
参数和 return 值的显式生命周期注释的情况下无法编译 - lifetime elision rules 不适用于至少两个借用的论点。
但我很好奇 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
,在 lifetime elision 下:
Each elided lifetime in input position becomes a distinct lifetime parameter.
您可以尝试将函数分配给错误的类型。编译器会告诉你函数的正确类型:
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
。
一种思考方式是,我们不是 'giving' 带有生命周期注释的生命周期,而是描述 return 值的生命周期如何与输入的生命周期相关。
生命周期已经存在,但是注释让我们可以设置它们之间的关系。由于您永远不会将 query
的生命周期与情况 2 中的任何其他内容相关联,因此我们真的不需要命名它。直观地说,这是最常见的情况,如果您没有对 query
.