Rust的生命周期尽管细化了一些编程语言中的类型,但没有细化完全,或者说在Rust中有些符号滥用,关系表示的并不是那么明晰。用不严谨的类型论的符号可以表示如下。需要注意的就是生命周期可以视作类型的“类型”,用T : 'a
表示,而生命周期之间的关系则是同一层级的类型之间的关系用'a <: 'b
表示'a
的生命周期长于'b
。
1 2 3 4 5 6 7 8 9 10 11 12 13
| 'static 是 'a 的子类型, 'a 是 'b 的子类型, 即: 'static <: 'a <: 'b
i32 : 'static String : 'static T : 'static
若T : 'static, 则&T = &'a T : 'a. 这里的&T似乎应该视作&'a T. 万恶的自动推导将细节隐藏起来了. 暴论: Rust的学习难度就是因为这些干扰语言一致性的语法糖造成的。
若T : 'a, 则&'static T : 'static
若'a <: 'b, 设&'a T : 'x, &'b T : 'y, 则'x = 'a <: 'b = 'y.
|
总结一下:
1 2 3
| 'static <: 'a <: 'b &'x T : 'x &T将被自动推导为&'a T
|
具体验证请见下述代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| fn f<T>(_: T) where T: 'static, { }
fn g<'a, T>(_: &'static T) where T: 'a, { }
fn h<'a, T>(_: &'a T) where T: 'static, { }
fn hh<T>(_: &T) where T: 'static, { }
fn main() { let x = 0; f(x); h(&x); hh(&x); static Y: i32 = 0; f(Y); f(&Y); g(&Y); h(&Y); hh(&Y); }
|
其中需要注意的是Rust允许&'b &'a mut i32
这种类型,并且T包含这种可能性。下面再补充一下关于Rust的借用的代码:
1 2 3 4 5 6
| fn main() { let mut x: i32 = 0; let mut x_mut: &mut i32 = &mut x; let x_mut_ref: &&mut i32 = &x_mut; let x_mut_mut: &mut &mut i32 = &mut x_mut; }
|