Rust 如何用生存期初始化变量?

Rust 如何用生存期初始化变量?,rust,lifetime,Rust,Lifetime,我有以下代码,不知道如何使其工作: fn new_int<'a>() -> &'a isize { &5 } fn main() { let x = new_int(); } fn new\u int你不能。生存期参数不允许您选择值的生存期,它只允许您与编译器通信,说明两个或多个引用与同一内存“相关”,并且预期共享同一生存期 函数(如您的示例中的new\u int)可以通过两种方式分配内存: 本地位于分配给函数本身的区域中,当您从函数(堆栈

我有以下代码,不知道如何使其工作:

fn new_int<'a>() -> &'a isize {
    &5
}

fn main() {
    let x = new_int();
}

fn new\u int你不能。生存期参数不允许您选择值的生存期,它只允许您与编译器通信,说明两个或多个引用与同一内存“相关”,并且预期共享同一生存期

函数(如您的示例中的
new\u int
)可以通过两种方式分配内存:

  • 本地位于分配给函数本身的区域中,当您从函数(堆栈)返回时将被销毁
  • 动态地在所有函数(堆)共用的内存区域中
引用(
&
)是指向内存区域的指针。它可以指向本地堆栈,也可以指向堆。由于动态分配在性能上比在堆栈上写入要昂贵得多,Rust默认使用堆栈(必须使用一个框来执行动态分配)

简而言之,这就是为什么你的代码是非法的:

fn new_int<'a>() -> &'a isize {
    let a: &'a isize = &5; // write 5 on the function's local stack
    a // return a pointer to that area of memory
} // the function ends and its stack (where I wrote 5) is destroyed
  // so the pointer I'm trying to return is no longer valid
或者执行动态分配(在isize的情况下,这是一种过度的分配,但如果您实际使用的是大型结构,则可能有意义)

同样,在这种特定情况下(即,您的函数总是返回5或其他静态已知值,而不是由函数动态计算的值),您也可以返回一个具有
“静态
生存期的引用:

fn new_int<'a>() -> &'a isize {
    static FIVE: isize = 5;
    &FIVE
}
let i: &'static isize = new_int();

理解原因的另一种方式

fn new_int<'a>() -> &'a isize {
    &5
}
但是,
&5
不能有
的静态
生存期,因此该函数被拒绝


换句话说,这样的声明本质上是说“我可以给你一个你想要的任何一生的参考”。当然,只有当从函数返回的引用是
静态的
生存期时,这才有效,这是可能的最大生存期。这就是DK。顺便说一下,生命周期只描述代码已经在做什么。它们不会以任何方式影响代码的行为

它们不是一条指令,用来让某些东西按要求的时间运行,而是一种一致性检查,确保代码实际执行它所说的操作

事实上,在检查代码后,锈迹会从代码中去除所有生命周期,然后编译代码而不知道生命周期


变量在其作用域结束时被销毁,这就是它们的生存期。您不能说声明他们没有这样做。

我不知道您想做什么,但您所做的是尝试创建对生存期小于“a”的值的引用。它具有函数体的生存期。我试图用生存期参数将该变量暴露到函数体外部。如果可能的话,这个变量在函数体之外是死的。如果您可以访问它,您将覆盖其他内存。错误消息(请参阅)确切地告诉您。由于
static
promotion,这些函数现在可以编译(请参阅丢弃我自己的进行中答案,但我想指出第三个选项:如果它总是返回
5
,或任何有限的答案集,则可以返回对静态变量的借用引用:
static FIVE:isize=5;
,然后作为函数的结果返回
&FIVE
)。
// new_int does not return anything. Instead it mutates
// the old_int in place
fn new_int(old_int: &mut isize) {
    *old_int = 5;
}

fn main() {
    let mut a = 2; // memory for an int is allocated locally
                   // in main()
    new_int(&mut a); // a mutable reference to that memory is passed
                     // to new_int, that overwrites it with another value
}
fn new_int<'a>() -> &'a isize {
    static FIVE: isize = 5;
    &FIVE
}
fn new_int<'a>() -> &'a isize {
    &5
}
let i: &'static isize = new_int();