生命周期
入门
简单代码
fn main() {
let myage;
{
let age = 19;
myage = &age;
}
println!("{}", myage);
}
问题:
age
does not live long enough borrowed value does not live long enoughrustcE0597main.rs(12, 5):
age
dropped here while still borrowedmain.rs(13, 20): borrow later used here`
说明age
只在这个代码块里存活,如果通过引用进行“拿”出去调用,则无法使用。所以rust
会有一个内置的生命周期检测。
判断规则:myage所处的生命周期,引用了比他小的生命周期里的age数据,会认为你的生命周期代码有误,不能编译。
demo2:比较大小的函数
mod api;
mod models;
fn max(a: i32, b: i32) -> i32 {
if a > b {
a
} else {
b
}
}
fn main() {
let a = 12;
let b = 21;
println!("最大值是: {}", max(a, b));
}
我们来换成引用方式,就得告诉max
函数,你调用的a
和b
的引用属于哪个生命周期,定义方式是一个单引号加你自己定义的一个生命周期的名称,比如:'a
,只有左侧一个单引号。
fn max<'a>(a: &'a i32, b: &'a i32) -> &'a i32 {
if a > b {
a
} else {
b
}
}
fn main() {
let a = 12;
let b = 21;
println!("最大值是: {}", max(&a, &b));
}
这里的'a
,里面的a仅仅是一个标记📌而已,不用过多在意它叫什么,而是要在意它这里要加。
在struct中使用引用属性
#[derive(Debug)]
struct User<'a> {
id: &'a i32,
}
fn main() {
let mut id = 11;
let u = User { id: &id };
println!("{:?}", u);
id = 107;
println!("{:?}", id);
}
上述这样是没问题的,但是改成这样
#[derive(Debug)]
struct User<'a> {
id: &'a i32,
}
fn main() {
let mut id = 11; // 好比是我的东西
let u = User { id: &id }; // 东西被 u 借走了
id = 107; // 不能使用
println!("{:?}", u); // 还在 u ,没还,这个代码下面没有任何地方使用u 就可以继续使用 id
}
#[derive(Debug)]
struct User<'a> {
id: &'a i32,
}
fn main() {
let mut id = 11; // 好比是我的东西
let u = User { id: &id }; // 东西被 u 借走了
id = 107; // 不能使用
println!("{:?}", id); // 可以继续使用id
}
&str
记得前面写这个的时候,总会加上一个&'static str
,所以这也是跟生命周期有关。
let name = "wujie";
注意
它的本质是str
,而且是被保存在“二进制文件中的”,使用的时候使用引用的方式来借用它。因此它的生命周期是static
,static
生命周期贯穿于整个程序,因此严格来说叫静态生存期。
fn show_name(name: &'static str) -> &'static str {
name
}
fn main() {
let name = "lisi";
show_name(name);
}
或者
fn show_name<'a>(name: &'a str) -> &'a str {
name
}
只要name
的生命周期不大于返回值的生命周期即可。