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

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

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

或者另一种try :

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

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

推荐答案

不能.lifetime参数不允许您 Select 值的生命周期 ,它只允许您与编译器通信,说明两个或多个引用与同一内存"相关",并且预期共享同一生命周期.

一个函数(比如new_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

您可以返回值

fn new_int() -> isize {
    5
}

fn main() {
    let a = new_int(); // the value 5 (not a pointer) is copied into a
}

或者执行动态分配(在isize的情况下,这是过分的,但如果您实际使用的是大型 struct ,这可能是有意义的)

fn new_int() -> Box<isize> {
    Box::new(5) // a Box allocates memory and writes in the heap
}

fn main() {
    let a = *new_int();
}

或者,您可以在函数外部分配内存,并在函数中对其进行变异.您通常不会对基元类型执行此操作,但在某些情况下(例如,数据流)这样做是有意义的:

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

作为@dk mentions in the comment below,,在这种特定情况下(即,您的函数总是返回5或其他静态已知值,而不是函数动态计算的值),您还可以返回'static生存期的引用:

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

你可以阅读更多关于staticin the Rust Reference年的信息.

从Rust 1.21开始,这种"静态升级"现在会自动为您执行,并编译您的原始代码.它创造了static FIVE的类似功能.

Rust相关问答推荐

如何将元素添加到向量并返回对该元素的引用?

如何在Rust中实现Functor trait?

我如何在Rust中使用传递依赖中的特征?

在Rust中赋值变量有运行时开销吗?

当第二个`let`依赖于第一个`let()`时,如何在一行中有多个`let()`?

对于已经被认为是未定义行为的相同数据,纯粹存在`&;[u32]`和`&;mut[u32]`吗?

不能在一个代码分支中具有不变的自身borrow ,而在另一个代码分支中具有可变的self borrow

是否可以在不切换到下一个位置的情况下获得迭代器值:

装箱特性如何影响传递给它的参数的生命周期 ?(举一个非常具体的例子)

是否可以使用Serde/Rust全局处理无效的JSON值?

如何迭代存储在 struct 中的字符串向量而不移动它们?

将泛型中的 Box 转换为 rust 中的 Box

如何为已实现其他相关 std trait 的每个类型实现一个 std Trait

str 和 String 的 Rust 生命周期

分配给下划线模式时会发生什么?

将 `&T` 转换为新类型 `&N`

使用部分键从 Hashmap 中检索值

Rustlings 切片原语

使用 `.` 将 T 转换为 &mut T?

返回 &str 但不是 String 时,borrow 时间比预期长