Rust: Lifetime小心要你命!

时间:2023-01-25 05:34:23

很多地方,并没有把lifetime的例子讲得更有普遍性,看了还是一知半解。

没有引用,也就是没有lifetime。我想用引用也是为了更加流畅,运行更快。如果你不想用lifetime,你只需不用或者尽量不用引用,也就ok了。

当然,今天,还是希望更多探讨一下让人一知半解的lifetime。

典型的举例(RustPrimer一书中):

fn foo<'a, 'b: 'a>(x: &'a str, y: &'b str) -> &'a str {
if true {
x
} else {
y
}
}

但是,更普遍的例子(以下都可以编译通过):

struct foo<'a> {
name: &'a str,
old: f32,
}
//以上在的例子有普遍性,因为有引用的类型。
//对foo实现具体的方法
impl<'a, 'b: 'a> foo<'a> {
// 无返回函数的类型,&'a self可以用 &self代替,即不需要显性生命周期的表达。
fn get_info(&'a self) {
let info = format!("{0}{1}", self.name, self.old);
println!("{}", info);
}
// 返回的是非引用类型,同样,也不需要显性生命周期的表达。

fn insert_info(&'a self, input: &'a str) -> String {
format!("{0}{1}{2}", self.name, self.old, input) //=>String
}
//返回的是非引用类型,也不需要显性生命周期的表达。
fn insert_info1(&self, input: &str, input2: &str) -> String {
format!("{0}{1}{2}{3}", self.name, self.old, input, input2)
}
// 返回的是引用,涉及多个引用,需要有显性生命周期的表达。
fn insert_info2(&'a self, input: &'a str) -> &'a str {
let info2 = format!("{0}{1}{2}", self.name, self.old, input);
let info3 = self.name.to_string() + input;
println!("{} {}", info2,info3);
// 是否可以把info2,info3的引用,做为返回值呢?
// info2,info3的作用域都在本函数中,生命周期不足。
// &info2 =>你想把info2的引用作为返回值?=>info2 does not live enough long
// &info3 =>你想把info3的引用作为返回值?=>info3 does not live enough long
input //这个做为返回值是可以的,生命周期'a,刚好匹配。
}
}

对于fn insert_info2函数,如果的确想把info2或info3的结果返回,那就只能选型值返回,而不能是引用返回,比如象fn insert_info函数。