作者:小娟2502895183 | 来源:互联网 | 2023-06-26 14:53
在下面的一段代码中,我试图了解通用生命周期参数'a
是如何特化的。
struct Wrapper<'a>(&'a i32);
fn foo() {
let mut r;
{
let x = 0; // the lifetime of x, call it 'x, starts from here |
r = Wrapper(&x); // 'a parameter in Wrapper is specialized to 'x |
drop(r); // |
} // --------------------------------- 'x ends here |
{
let y = 0; // the lifetime of y, call it 'y, starts from here |
// 'y is distinct from 'x |
// neither outlives the other one |
r = Wrapper(&y); // why 'a parameter can again be specialized to 'y? |
drop(r); // |
} // ------------------------------------ 'y ends here |
}
为什么可以将通用生命周期参数'a
专门用于两个不相交的生命周期,'x
并且'y
对于一个对象'r
?
从另一个角度来看,我对r
. 从Rustonomicon 中的子类型和差异章节,我明白生命周期'a
是泛型类型的一部分Wrapper<'a>
。当泛型变得专门化时,它不能是Wrapper<'x>
或Wrapper<'y>
。那么什么是类型r
呢?
也许更高级别的特征边界与它有关?
如果有人能解释 Rust 编译器如何在内部解释这一点,我将不胜感激。
更新:
现有答案表明 的生命周期r
可以有多个起点和终点。如果这是真的,那么'r
是'x
和 的并集'y
。然而,这种解释并不符合子类型规则。例如,考虑下面的代码,另一个的子类型'r2
也不'r
是(或寿命更长),所以我们应该不能调用bar(r, r2)
,但我们实际上可以。矛盾。
struct Wrapper<'a>(&'a i32);
fn bar<'a>(_p: Wrapper<'a>, _q: Wrapper<'a>) {}
fn foo() {
let mut r;
{
let z = 0;
let r2 = Wrapper(&z); // -> |
{ // |
let x = 0; // -> | // +--'r2
r = Wrapper(&x); // |--'x--+ // |
bar(r, r2); // | | // <- |
} // <- | |
} // |
{ // +--'r
let y = 0; // -> | |
r = Wrapper(&y); // |--'y--+
drop(r); // |
} // <- |
}