如何使用生命周期初始化变量? [英] How to initialize a variable with a lifetime?

查看:69
本文介绍了如何使用生命周期初始化变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have following code and don't know how to get it working:

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

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

或其他尝试:

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

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

推荐答案

您不能.生命周期参数不允许您选择一个值的生存时间,它仅允许您向编译器传达两个或多个引用与同一内存相关"并期望共享相同生命周期.

You can't. A lifetime parameter does not allow you to choose how long a value lives, it only allows you to communicate to the compiler that two or more references are "related" to the same memory and are expected to share the same lifetime.

一个函数(例如您的情况下的new_int)可以通过两种方式分配内存:

A function (like new_int in your case) can allocate memory in two ways:

  • 本地位于分配给函数本身的区域(堆栈)中,当您从函数返回时会被破坏
  • 动态地在所有功能共有的内存区域(通常称为堆",尽管不一定在所有情况下都正确)

引用(&)是指向内存区域的指针.它可以指向本地堆栈,也可以指向堆".由于在性能方面动态分配比在堆栈上写入要贵得多,因此Rust默认使用堆栈(您必须使用Box来执行动态分配).

A reference (&) is a pointer to an area of memory. It can point to the local stack, or to "the heap". Since dynamic allocations are much more expensive in terms of performance than writing on the stack, Rust uses the stack by default (you have to use a Box to perform a dynamic allocation).

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

So, in a nutshell, this is why your code is illegal:

fn new_int<'a>() -> &'a isize {
    let a: &'a isize = &5; // write 5 on the local stack
    a // return a pointer to that area of memory
} // the area of memory where I wrote 5 is destroyed here,
  // so the pointer I'm trying to return is not valid

您可以返回值

fn new_int() -> isize {
    5
}

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

或执行动态分配(在进行isize的情况下会显得过大,但如果您实际上是在使用大型结构,则可能有意义)

or perform a dynamic allocation (which is overkill in case of an isize but might make sense if you're actually working with a big structure)

fn new_int() -> Box<isize> {
    Box::new(5)
}

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

或者,您可以在函数外部分配内存,并在函数中对其进行更改.您通常不对原始类型执行此操作,但是在某些情况下(例如数据流)它是有意义的:

alternatively, you can allocate memory outside of the function and mutate it in the function. You don't typically do it for a primitive type, but it makes sense in some scenarios (e.g. streaming of data):

// 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在以下评论中提到, ,在这种特定情况下(即您的函数始终返回5或其他静态已知值,而不是函数动态计算的值),您还可以返回具有'static生存期的引用:

As @dk mentions in the comment below,, in this specific case (i.e. your function always returns 5 or some other statically known value, not something calculated dynamically by the function) you can also return a reference with a 'static lifetime:

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

您可以在Rust参考中阅读有关'static 的更多信息.

You can read more about 'static in the Rust Reference.

从Rust 1.21开始,现在将自动为您执行此静态升级",并编译原始代码.它创建与static FIVE等效的文件.

As of Rust 1.21, this "static promotion" is now performed for you automatically and your original code compiles. It creates the equivalent of the static FIVE.

这篇关于如何使用生命周期初始化变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆