0
点赞
收藏
分享

微信扫一扫

Rust 生命周期

mm_tang 2022-02-21 阅读 118

Rust 生命周期

let a=String::from("a");
let b=&a;//b的诞生 ,后续没有在使用b,所以b死亡

在借用者生命期间,所有者必须是活的,不然就会产生悬垂引用,幸运的是我们不用关注它,交给编译器来提示,编译器通过生命周期来检查
大部分时候生命周期是隐含并可以推断的,但有些情况就无法推断了,需要程序员自己指出

fn longest(x: &String, y: &String) -> &String {//这个函数会报错,具体原因我们后面会讲到
	if x.len() > y.len() {//可以理解成随机返回 x 或 y,因为在运行时2种情况都会出现
		x
	} else { 
		y 
	}
}
fn main() {
	let a=String::from("a");
	let c;
	{
		let b=String::from("b");
		c = longest(&a,&b);//我们并不知道它会返回a还是b,这导致生命周期的不确定性,那么此时c就是不安全的,你不敢在大括号外使用c
	}
}

下面是修改后

fn longest<'a>(x: &'a String, y: &'a String) -> &'a String {//统一生命周期,按照最小生命周期来分析
	if x.len() > y.len() {
		x
	} else {
		y
	}
}
fn main() {
	let a=String::from("a");
	let c;
	{
		let b=String::from("b");
		c = longest(&a,&b);
		println!("{}",c);//安全
	}//b在这里就死了
	// println!("{}",c);//这行会报错,因为最小生命周期是b
}

函数或方法的参数的生命周期被称为 输入生命周期,而返回值的生命周期被称为 输出生命周期
隐式生命周期,官方介绍了3条规则

  1. 每一个是引用的参数都有它自己的生命周期参数
  2. 如果只有一个输入生命周期参数,那么它被赋予所有输出生命周期参数
  3. 如果方法有多个输入生命周期参数并且其中一个参数是 &self 或 &mut self, 那么所有输出生命周期参数被赋予 self 的生命周期

你应该意识到了,其实都是隐式存在生命周期的,上面只不过是编辑器无法分析,要求我们显式声明

fn f(x:&i32){}
fn f<'a>(&'a i32){}

fn f2(x:&String)->&String{}
fn f2<'a>(x:&'a String)->&'a String{}
//为什么返回值一定是'a ,因为如果是函数内部的所有者,那么返回出去的借用者就是 悬垂引用,因为在退出函数时 那个所有者就死了
//所以当 参数们只有一个生命周期时,那么返回值也一定是那个生命周期

fn f3(x:&i32,y:&i32,...){}
fn f3<'a,'b,...>(x:&'a i32,y:&'b i32,...){}
//再多参数也是这样,没必要显式声明,咱就懒点

fn f4<'a,'b>(x:&'a String,y:&'b String) -> &'a String {
	// &String::from("") //报错,生命周期不是'a
	// &y	//报错,原因同上
	&x
}

关于第三条,特别说明一下

impl ABC {//如果ABC 是一个加工用的对象,那么就不应该返回&self的生命周期
	fn f1(&self,a:&String)->&String{//返回的生命周期是&self的
		a //报错因为生命周期不同
	}
	fn f2<'a>(&self,a:&'a String)->&'a String{//但是可以这样
		a
	}
}

结构体定义

struct ABC<'a>{
	A:&'a i32
}
impl<'a> ABC<'a> {
	fn f1(x:&'a i32){}
	fn f2(&self,x:&'a i32){}
}
struct ABCD<'a>{//一样
	A:&'a i32,
	B:&'a i32
}
struct ABCDE<'a,'b>{//不一样
	A:&'a i32,
	B:&'b i32
}

静态生命周期

'static 其生命周期能够存活于整个程序期间

白话说就是 它是否真的可以存活整个程序期间,不是靠'static,而是这个引用是否真实可以存活,前面提到:生命周期声明类似于变量类型声明,不会改变对象的真正生命周期,所以’'static’只是告诉编译器而已

所有的字符串字面值(&str)都拥有 'static 生命周期


参考:
官方文档
知乎 - Rust生命周期

举报

相关推荐

0 条评论