生命周期定义了引用有效的范围。
生命周期是隐含的和推断的。
rust使用通用生命周期参数来确保使用有效的实际引用。
当程序试图访问无效引用时称为悬空引用,所指向无效资源的指针称为悬空指针。
看看一个简单的例子:
fn main()
{
let a;
{
let b = 10;
a = &b;
}
println!("a : {}",a);
}
输出结果如下 -
在上面的示例中,外部作用域包含a
变量,并且它不包含任何值。 内部范围包含变量b
,它存储的值为10
。b
变量的引用存储在变量a
中。 当内部范围结束时,尝试访问a
的值。 rust编译器将抛出一个编译错误,因为a
变量指的是变量的位置超出了范围。 rust将使用借用检查器确定代码无效。
借用检查器用于解决悬挂引用的问题。 借用检查器用于比较范围以确定它们是否有效。
在上面的例子中,注释了a
变量的生命周期,a
和b
变量的生命周期带有b
变量。 在编译时,rust将拒绝该程序,因为a
变量的生命周期大于b
变量的生命周期。 可以修复上面的代码,以便不会发生编译器错误。
在上面的例子中,a
变量的生命周期短于b
变量的生命周期。 因此,上面的代码运行时没有任何编译错误。
生命周期注释语法应遵循的步骤:
'
)撇号开头。'a
。&
之后,然后是空格以将注释与引用类型分开。生命周期注释语法的一些示例:
&i32
// reference& 'a i32
// reference with a given lifetime.& 'a mut i32
// mutable reference with a given lifetime.'a
代表参考的生命周期。每个参考都有与之相关的生命周期。也可以在函数签名中使用生命周期注释。 通用生命周期参数在角括号<>
之间使用,角括号放在函数名和参数列表之间。
示例 -
fn fun<'a>(...);
在上面的例子中,fun
是具有一个生命周期的函数名,即'a
。 如果函数包含两个具有两个不同生命周期的参考参数,则它可以表示为:
fn fun<'a,'b>(...);
如果'y'
是不可变引用,那么参数列表将是:
fn fun<'a>(y : & 'a i32);
如果'y'
是可变引用,那么参数列表将是:
fn fun<'a>(y : & 'a mut i32);
两个&'a i32
和&'a mut i32
都很相似。 唯一的区别是'a
放在&
和mut
之间。
&mut i32
的意思是“对i32的可变引用”。&'a mut i32
表示“对具有生命周期’的i32
的可变引用”。
也可以在结构中使用显式生命周期,就像在函数中使用的一样。
下面来看看一个示例:
struct example
x : & 'a i32, // x is a variable of type i32 that has the lifetime 'a.
下面来看一个简单的例子:
struct example<'a> {
x: &'a i32,
}
fn main() {
let y = &9;
let b = example{ x: y };
println!("{}", b.x);
}
执行上面示例代码,得到以下结果 -
9
可以实现具有生命周期'a
使用impl
块的结构类型。
下面来看一个简单的例子:
struct example<'a> {
x: &'a i32,
}
impl<'a> example<'a>
{
fn display(&self)
{
print!("value of x is : {}",self.x);
}
}
fn main() {
let y = &90;
let b = example{ x: y };
b.display();
}
执行上面示例代码,得到以下结果 -
value of x is : 90
有两种可能性:
当引用具有相同的生命周期时。
fn fun <'a>(x: & 'a i32 , y: & 'a i32) -> & 'a i32
//block of code.
在上述情况下,引用x
和y
都具有相同的生命周期,即'a
。
当引用具有不同的生命周期时。如下 -
fn fun<'a , 'b>(x: & 'a i32 , y: & 'b i32)
// block of code.
在上述情况下,参考x
和y
都具有不同的生命周期,即分别为'a
和'b
。
‘static
'static
的生命周期是特殊的生命周期。它表示某些东西具有生命周期'static
将在整个程序中具有生命周期。 主要是'static
生命周期与字符串一起使用。 具有“静态生命周期”的引用对整个程序有效。
示例 :
let s : & 'static str = "h3 tutorial" ;
生命周期椭圆是一种推理算法,它使常见的模式更符合人体工程学。生命周期椭圆使一个程序被淘汰。
生命周期椭圆可以在任何地方使用:
& 'a t
& 'a mut t
t<'a>
生命周期椭圆可以以两种方式出现:
示例 -
fn fun<'a>( x : & 'a i32); // input lifetime
fn fun<'a>() -> & 'a i32; // output lifetime
fn fun<'a>(x : & 'a i32)-> & 'a i32; // both input and output lifetime.