Rust 生命周期参数的语义
考虑以下示例:Rust 生命周期参数的语义,rust,reference,lifetime,borrow-checker,ownership,Rust,Reference,Lifetime,Borrow Checker,Ownership,考虑以下示例: fn main(){ 设string1=String::from(“abcd”); 设string2=“xyz”; 让结果=最长(string1.as_str(),string2); println!(“最长的字符串是{}”,result); } fn.y.len(){ x }否则{ Y } } 据说(我的) 函数签名现在告诉Rust,对于某些生存期'a,函数接受两个参数,这两个参数都是至少与生存期'a相同的字符串片段函数签名还告诉Rust,从函数返回的字符串片段将至少与生命周
fn main(){
设string1=String::from(“abcd”);
设string2=“xyz”;
让结果=最长(string1.as_str(),string2);
println!(“最长的字符串是{}”,result);
}
fn.y.len(){
x
}否则{
Y
}
}
据说(我的)
函数签名现在告诉Rust,对于某些生存期'a
,函数接受两个参数,这两个参数都是至少与生存期'a
相同的字符串片段函数签名还告诉Rust,从函数返回的字符串片段将至少与生命周期'a
一样长。实际上,这意味着longest
函数返回的引用的生命周期与传入的引用的生命周期中较小者相同。这些约束是我们想要强制执行的
粗体的句子不应该是吗?函数签名还告诉Rust,从函数返回的字符串片段将在最长的'a
寿命内生存。?这样,我们可以确信,只要x
和y
都是活动的,那么返回值也将是有效的,因为后者引用前者
换言之,如果
x
、y
和返回值的寿命至少与'a
的寿命一样长,那么编译器可以简单地让'a
成为一个空范围(任何项都可以超过该范围)以满足限制,从而使注释无效。这是没有意义的,对吧? 我们可以从示例代码中考虑轻微修改范围的情况。
fn main(){
设string1=String::from(“abcd”);
{
设string2=“xyz”;
让结果=最长(string1.as_str(),string2);
println!(“最长的字符串是{}”,result);
}
}
fn.y.len(){
x
}否则{
Y
}
}
这里,我们认识到,对于上面的函数调用最长的,生存期a
最终是string2
的生存期,因为x
和y
必须至少与a
一样长,所以如果a
是string1
的生存期,然后,longest
的第二个参数,即string2
的有效期不会比string1
长,并且“两个参数的有效期必须至少与a
的有效期一样长”的语句将为false
我们承认生存期a
是string2
的生存期。我们知道,longest
返回的字符串片段可以是string1
或string2
。由于我们在声明中做了一个约束,即返回值的寿命至少与a
的寿命一样长,因此我们实际上是说返回值的寿命至少与string2
的寿命一样长,即两个寿命中较短的字符串
如果longest
返回string2
,则返回的字符串片段将与a
的生存期一样长。但是,如果longest
返回string1
,则返回的字符串片段将与string1
的生存期一样长,这比生存期a
(string2
的生存期)更长,因此,我们说从函数返回的字符串片段将至少与a
一样长
这里需要注意的一点是,我们不知道哪个片最长
将返回,因此我们只允许返回的引用的生存期是两个生存期中较小的一个,因为在两个生存期中较小的一个期间,两个字符串肯定仍然有效。用形式语言表示,注释转换为:
对于所有“a”,a≤'x和'a≤'y意味着“a”≤'r
使用'x
、'y
和'r
分别计算x
、y
的生存期和返回值
这将返回值的生存期链接到参数的生存期,因为要使该关系对所有“a”保持不变,则必须具有'x≤'r
或'y≤'r
编译器将分两次使用该注释:
编译带注释的函数时,编译器不知道x
和y
的实际生存时间,也不知道'a
(因为'a
将在调用站点上选择,就像所有通用参数一样)。但是它知道,当调用函数时,调用方将使用一些与输入约束相匹配的生存期'a
≤'x
和'a≤'y
并检查函数的代码是否遵守输出约束'a≤'r
'a
,其中可以访问返回值,以及'a的约束≤'x
和'a≤'y
加上由于周围代码而需要的任何额外约束,特别是x
和y
的来源以及返回值的使用方式。如果编译器能够找到与所有约束匹配的某个作用域'a
,那么代码将使用该作用域进行编译。否则编译将失败,并出现“寿命不够长”错误
不,它至少应该活着,因为如果它活得更长,它仍然是一个有效的生命。@Netwave但它不会有效,它活得太长,例如,它比
x
和y
都活得长。啊,啊哈,好的。我误解了。在这种情况下,x和y都受相同生存期的约束,因此返回的引用最多可以像您所说的那样生存。有道理是的。因此,调用者是有保证的
fn main() {
let string1 = String::from("abcd");
let string2 = "xyz";
let result = longest(string1.as_str(), string2);
println!("The longest string is {}", result);
}
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}