首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >泛型生存期是以引用的生存期还是引用值的生存期来实现的?

泛型生存期是以引用的生存期还是引用值的生存期来实现的?
EN

Stack Overflow用户
提问于 2019-08-12 05:57:19
回答 1查看 115关注 0票数 3

考虑以下方案:

代码语言:javascript
复制
fn main() {
    let c;                                      |<-'a
    let mut a = "Hello, world!".to_string();    |
    {                                           |
        let b = &mut a;           |<-'b         |
        c = foo(b);               |             |
    }                                           |
    println!("{}", c)                           |
}

fn foo<'z>(a: &'z mut str) -> &'z str {
    a
}

b的生存期为'b,而c的生存期为'a,这比'b长。foo的生存期约束规定foo的返回值(在本例中为c)应该与其参数具有相同的生存期(在本例中为b)。foo的生存期约束如何满足?

但是,这个程序是编译的,所以我想foo的生存期参数'z会变成b的引用值(a)的生存期,从而满足foo的生存期约束。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-12 16:56:14

一个值有它自己的生命周期,但是引用也会跟踪它引用的事物的生存期。不幸的是,这里缺少官方术语。我(和其他一些人)已经开始使用的术语是具体的生命周期。主变量有三个,因此有三个具体的生命周期:

代码语言:javascript
复制
fn main() {
    let c;                     //       'c
    let mut a = String::new(); // 'a     ¦
    {                          //  |     ¦
        let b = &mut a;        //  | 'b  ¦
        c = foo(b);            //  |  |  |
    }                          //  |     |
    println!("{}", c)          //  |     |
}

aStringb&mut Stringc&str。这三个变量都是值,但bc也是引用。在本例中,b引用a中的值,是&'a mut String。由于c是从b派生的,所以它具有相同的“内部生存期”:&'a str

值得注意的是,b本身的生命周期--从不使用--起了作用。这是非常罕见的,因为你需要可变的借款和“额外的”借款:

代码语言:javascript
复制
fn main() {
    let c;
    let mut a = String::new();
    {
        let mut b = &mut a;
        c = foo(&mut b);    // Mutably borrowing `b` here
    }
    println!("{}", c)
}
代码语言:javascript
复制
error[E0597]: `b` does not live long enough
 --> src/main.rs:6:17
  |
6 |         c = foo(&mut b);
  |                 ^^^^^^ borrowed value does not live long enough
7 |     }
  |     - `b` dropped here while still borrowed
8 |     println!("{}", c)
  |                    - borrow later used here

在本例中,传递给foo的值为&'b mut &'a mut String类型,该类型被强制传递到&'b mut str。值b的生存期不够长,因此您将得到错误。

我认为这种模式不能解释更复杂的借贷关系。例如,如果aprintln!之后再次使用,则可变的借入不能用于a的整个生命周期。

a的可变借用由c持有,但借用的持续时间不需要与c的生存期相对应。由于non-lexical lifetimes (在这种上下文中称为“非词法借用”),c持有的a的借用可以在println!之后但在范围结束之前终止。

从上面增强图表,以显示值的生存期和括号中引用的值的生存期:

代码语言:javascript
复制
fn main() {
    let c;                     //           'c
    let mut a = String::new(); // 'a         ¦
    {                          //  |         ¦
        let b = &mut a;        //  | 'b('a)  ¦
        c = foo(b);            //  |  |('a)  |('a)
    }                          //  |         |('a)
    println!("{}", c);         //  |         |('a)
                               //  |         |
    println!("{}", a);         //  |         |
}

另请参阅:

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57456244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档