Rust 为什么可以';引用的生命周期是否可以推断为所有上下文可能性中最短的?
下面是一个代码示例,我测试了两个Rust 为什么可以';引用的生命周期是否可以推断为所有上下文可能性中最短的?,rust,lifetime,template-argument-deduction,object-lifetime,return-type-deduction,Rust,Lifetime,Template Argument Deduction,Object Lifetime,Return Type Deduction,下面是一个代码示例,我测试了两个&str并返回其中一个: fn bad_longest(s1: &str, s2: &str) -> &str { if s1.len() >= s2.len() { s1 } else { s2 } } 它没有编译请求显式生存期,所以我提供了它们: fn longest<'r, 'a, 'b>(s1: &'a str, s2: &'b str) -> &'r str where
&str
并返回其中一个:
fn bad_longest(s1: &str, s2: &str) -> &str {
if s1.len() >= s2.len() { s1 } else { s2 }
}
它没有编译请求显式生存期,所以我提供了它们:
fn longest<'r, 'a, 'b>(s1: &'a str, s2: &'b str) -> &'r str
where
'a: 'r,
'b: 'r
{
if s1.len() >= s2.len() { s1 } else { s2 }
}
我的问题是:我手动提供的生命周期不是可以从上下文中推断出来的吗?我是否遗漏了任何用例?函数签名中省略的生命周期永远不会从它们的使用方式中推断出来。有些完全基于签名本身:
- 参数中的每个省略寿命都成为一个不同的寿命参数
- 如果参数中只使用了一个生存期(省略或不省略),则该生存期将分配给所有省略的输出生存期
- 如果接收器的类型为&Self或&mut Self,那么对Self的引用的生存期将分配给所有省略的输出生存期参数
您的函数有两个非
self
参数,因此这些规则都不能为返回值提供生存期,因此需要显式的生存期。函数签名中省略的生存期永远不会从它们的使用方式中推断出来。有些完全基于签名本身:
- 参数中的每个省略寿命都成为一个不同的寿命参数
- 如果参数中只使用了一个生存期(省略或不省略),则该生存期将分配给所有省略的输出生存期
- 如果接收器的类型为&Self或&mut Self,那么对Self的引用的生存期将分配给所有省略的输出生存期参数
您的函数有两个非
self
参数,因此这些规则都不能为返回值提供生存期,因此需要显式的生存期。请注意,函数签名(包括生存期)永远不会从函数体中推导出来,以避免意外中断更改。也许这个事实就足够了。@Cerberus是一个伟大的捕获物!但是,在本地(无论如何都不能通过引用返回)和作为函数参数提供的(可能的最小值)之间是否存在生命周期?如果没有,我想我确实写了最短的生命周期,可以推断出来(但不是)。返回的生命周期也可以是'a
或'b
,甚至是'static
。生存期省略只是语法上的糖分,只是一些简单、容易的规则。当然,可以添加一个新的省略规则,内容是:未指定的返回生存期将完成,新的生存期将被限制为与任何输入生存期一样长。这将解决您的特殊情况,甚至可以向后兼容。不管这是不是一个好主意。。。我还没有意见。但是如果你担心当前解决方案的人体工程学,请注意,编写函数的生疏方法可能是:fn longest请注意,函数签名(包括生命周期)永远不会从它的身体推断出来,以避免意外的破坏性更改。也许这个事实就足够了。@Cerberus是一个伟大的捕获物!但是,在本地(无论如何都不能通过引用返回)和作为函数参数提供的(可能的最小值)之间是否存在生命周期?如果没有,我想我确实写了最短的生命周期,可以推断出来(但不是)。返回的生命周期也可以是'a
或'b
,甚至是'static
。生存期省略只是语法上的糖分,只是一些简单、容易的规则。当然,可以添加一个新的省略规则,内容是:未指定的返回生存期将完成,新的生存期将被限制为与任何输入生存期一样长。这将解决您的特殊情况,甚至可以向后兼容。不管这是不是一个好主意。。。我还没有任何意见。但是如果你担心你当前解决方案的人体工程学,请注意,编写函数的生疏方法就是:fn
static STATIC: &str = "123";
fn main() {
let auto = "123456";
let dyn_ = String::from("123456789");
println!(
"{}",
longest(
longest(STATIC, auto),
dyn_.as_str()
)
);
}