关于 rust 的生命周期的 困惑
学了很久,想搞清楚Rust的生命周期到底是干什么用的,可一直搞不明白,网上讲解 生命周期的文章很多,看完之后,我就更困惑了,我很难相信写这些文章的作者是真的理解了,不知道有没有高手,可以真正把这个问题说明白的。
帖一段代码来说明我的困惑:
fn s1<'a>(x: &'a i32) -> &'a i32 {
return &x;
}
fn s2<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
print!("{}", y);
return &x;
}
fn s3<'a, 'b: 'a>(x: &'a i32, y: &'b i32) -> &'a i32 {
print!("{}", x);
return &y;
}
fn main() {
let x = 1;
{
let y = 2;
let r1 = s1(&x);
print!("{}", r1);
let r2 = s2(&x, &y);
print!("{}", r2);
let r3 = s3(&x, &y);
print!("{}", r3);
let r4 = s3(&y, &x);
print!("{}", r4);
}
}
上面这个例子是可以正常工作的, 但它却让我彻底糊涂了,里面存在几个令人疑惑的问题:
1. 函数s2 中的'a 究竟是什么? 它要求x和y有相同的生存域,显然不是,因为例子中的x和y的生存域明显不同。那她到底代表什么含义?
如果把所有的'a 全部去除, 编译器也完全能够判断出返回值的生存域是否合法, 但是,rust却强制在每个参数位置写一次'a, 这个完全没有意义的行为到底是有什么用意呢?
2. 函数s3 的逻辑似乎清晰一点,从声明上看'a是x 的生存域, 'b是y 的生存域, 并且x的生存域在y的生存域之内, 返回值与x的生存域相同。
函数声明中,自以为是的定义了 'a 包含在'b 之内,然后让代码编译通过了,可实际的代码调用,却完全不是这么回事, s3(&x, &y)和s3(&y, &x)都是允许的,于是, “ 'a是x 的生存域, 'b是y 的生存域” 这个理解显然就是错误的
更让人难以理解的是'a 和'b 的包含关系完全是自己随意编造的, 你总是有办法编造一个方案让编译通过,那这样做编译器的所谓检查到底有什么价值?
按理来说只要指定好返回值的生存周期,rust不就自己能够来判断生存域是否合法了么,干嘛要搞出这么复杂的语法,让程序员写一遍呢?想必是有 什么原因的吧,但网上的教程实在是太简单了,没有人深度解释一下里面的机理,不知是否有高手可以代为解释一下。