第五章 多个生命周期参数
niconical opened this issue · 1 comments
页码与行数
- 第139页(印次:2019第二次)
- 图5-34以及下方解释
- rustc ver: 1.61.0
fn the_longest<'a,'b:'a>(s1: &'a str, s2: &'b str) -> &'a str {
if s1.len() > s2.len() { s1 } else { s2 }
}
main函数(调用the_longest)代码:
// 节选自代码清单5-32
let s1 = String::from("Rust");
let s1_r = &s1;
{
let s2 = String::from("C");
let res = the_longest(s1_r, &s2);
println!("{} is the longest", res); // Rust is the longest
}
代码清单5-34以及下方解释为什么在多生命周期参数下调用the_longest的第一个参数s1_r的生命周期'a长于&s2生命周期'b,但是the_longest的lifetime subtype却是'b:'a,即'b outlive ‘a,但是使用'a:'b以下代码也可以编译通过:
// change lifetime subtype
fn the_longest<'a:'b,'b>(s1: &'a str, s2: &'b str) -> &'b str {
if s1.len() > s2.len() { s1 } else { s2 }
}
所以”但为什么现在'b:'a表示’b的存活时间长于'a的呢?(p140)“这个问题似乎在隐含只可以使用'b:'a?
@niconical 说明你还没有理解生命周期参数的本质。
“为什么现在'b:'a表示’b的存活时间长于'a的呢?”
因为这就是编译器规则,语法就是这么规定的。生命周期参数语法就是给开发者来指定的,在你确定输入引用和输出引用的合法关系之后,如果需要指定'b:'a
,那就这么指定。不是让你滥用的。并不是说你随便指定个''a : 'b ',实际引用的生命周期就是这样的。 生命周期参数是开发者来辅助编译器来判断引用合法性,而不是让你修改引用的实际生命周期。
看你修改的这段代码。
fn the_longest<'a:'b,'b>(s1: &'a str, s2: &'b str) -> &'b str {
if s1.len() > s2.len() { s1 } else { s2 }
}
fn main() {
let s1 = String::from("Rust"); // 'a 的生命周期参数实例假如是 '1
let s1_r = &s1;
{
let s2 = String::from("C"); // 'b 的生命周期参数实例假如是 '2
let res = the_longest(s1_r, &s2); // 返回值res ( 'b) 的生命周期参数实例假如是 '3 ,
println!("{} is the longest", res); // Rust is the longest
}
}
注意:编译器检查只判断 输入位置和输出位置(返回值)的引用生命周期长短关系!!!
所以,现在满足 '1 的生命周期比 '3 长 , '1 : '3 ,符合the_longest 函数定义的生命周期参数约定 'a: 'b
编译器检测main里面实际调用函数的代码,符合你函数定义时生命周期参数约定,就会编译通过,表示你这段代码执行不会出现悬垂指针。
再回头看书里的示例:
fn the_longest<'a,'b:'a>(s1: &'a str, s2: &'b str) -> &'a str {
if s1.len() > s2.len() { s1 } else { s2 }
}
fn main() {
let s1 = String::from("Rust"); // 'a 的生命周期参数实例假如是 '1
let s1_r = &s1;
{
let s2 = String::from("C"); // 'b 的生命周期参数实例假如是 '2
let res = the_longest(s1_r, &s2); // 返回值 res ('a) 的 的生命周期参数实例假如是 '3
println!("{} is the longest", res); // Rust is the longest
}
}
注意:编译器检查只判断 输入位置和输出位置(返回值)的引用生命周期长短关系!!!
现在同样满足 满足 '2 的生命周期比 '3 长 , '2 : '3 ,符合the_longest 函数定义的生命周期参数约定 'b: 'a
当然都可以通过编译了。
另外: 建议你把书里内容完整看一遍,自己思考思考,再来提问题。也许等你思考完就不会有问题了。