fn xory<'a>(x: &'a str, y: &'a str) -> &'a str { x }
与使用两个生命周期相比,上述代码有什么优势?是否存在上述代码可以工作但 2 个生命周期不能工作的情况?
fn xory<'a>(x: &'a str, y: &'a str) -> &'a str { x }
与使用两个生命周期相比,上述代码有什么优势?是否存在上述代码可以工作但 2 个生命周期不能工作的情况?
这实际上取决于您的用例。鉴于您编写的确切代码:
fn xory<'a>(x: &'a str, y: &'a str) -> &'a str {
x
}
这里只使用一个生命周期是不利的,因为返回值仅取决于x
参数,而不取决于参数y
。让我们想象一下这个用户代码:
let x_in = "paul".to_owned();
let out = {
let y_in = "peter".to_owned();
xory(&x_in, &y_in)
};
我们希望这可以正常工作,因为out
基本上是x_in
. 但是编译器抱怨:
<anon>:12:22: 12:26 error: `y_in` does not live long enough
<anon>:12 xory(&x_in, &y_in)
^~~~
<anon>:13:7: 14:2 note: reference must be valid for the block suffix following statement 1 at 13:6...
<anon>:13 };
<anon>:14 }
<anon>:11:39: 13:6 note: ...but borrowed value is only valid for the block suffix following statement 0 at 11:38
<anon>:11 let y_in = "peter".to_owned();
<anon>:12 xory(&x_in, &y_in)
<anon>:13 };
这是因为编译器假设(从xory
签名中)输出xory
引用了两个参数。因此,通常最好尽可能详细地指定生命周期,以避免不必要的条件/假设/参数之间的关系。
在某些情况下,您只需要使用一个生命周期(或稍微不同的解决方案):假设您想要返回x
或y
根据某些条件返回:
fn xory<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() == 42 {
x
} else {
y
}
}
这里输出的生命周期取决于两个参数的生命周期,我们不知道编译时取决于哪一个。因此,我们必须为最坏的情况做好准备,并这样做。
在相同的生命周期中,您说返回值可以从x
or中借用y
,因此从函数体的角度来看,它更加灵活。从调用者来看,两者都更具限制性,x
并且y
只要保留结果就必须有效,而不仅仅是x
(比如说)。