Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 生命周期参数的语义_Rust_Reference_Lifetime_Borrow Checker_Ownership - Fatal编程技术网

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
        }
    }