函数调用中的生命周期
除了借用其参数之外,函数还可以返回借用的值:
#[derive(Debug)] struct Point(i32, i32); fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point { if p1.0 < p2.0 { p1 } else { p2 } } fn main() { let p1: Point = Point(10, 10); let p2: Point = Point(20, 20); let p3: &Point = left_most(&p1, &p2); println!("p3: {p3:?}"); }
'a
是一个泛型形参,由编译器推断出来。- 以
'
和'a
开头的生命周期是典型的默认名称。 - 将
&'a Point
读取为“借用的Point,至少 在
a` 生命周期内有效。- 当参数在不同的作用域时,“至少”部分至关重要。
在上述示例中,请尝试以下操作:
-
将
p2
和p3
的声明移至新作用域 ({ ... }
),以产生以下代码:#[derive(Debug)] struct Point(i32, i32); fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point { if p1.0 < p2.0 { p1 } else { p2 } } fn main() { let p1: Point = Point(10, 10); let p3: &Point; { let p2: Point = Point(20, 20); p3 = left_most(&p1, &p2); } println!("p3: {p3:?}"); }
请注意:由于
p3
的生命周期比p2
长,因此无法编译。 -
重置工作区,然后将函数签名更改为
fn left_most<'a, 'b>(p1: &'a Point, p2: &'a Point) -> &'b Point
。这不会被编译,因为'a
和'b
生命周期之间的关系不明确。 -
另一种解释方式:
- 对两个值的两个引用被一个函数借用,该函数返回 另一个引用。
- 它必须是来自这两个输入中的一个(或来自一个全局变量)。
- 是哪一个呢?编译器需要知道这一点,因此在调用点,返回的引用 的使用时间不会超过引用的来源中的变量。