我有以下代码,不知道如何让它工作:
fn new_int<'a>() -> &'a isize {
&5
}
fn main() {
let x = new_int();
}
Run Code Online (Sandbox Code Playgroud)
或者另一种尝试:
fn new_int<'a>() -> &'a isize {
let a: &'a isize = &5;
a
}
fn main() {
let x = new_int();
}
Run Code Online (Sandbox Code Playgroud)
Pao*_*lla 13
你不能.生命周期参数不允许您选择值存在多长时间,它只允许您与编译器通信两个或多个引用与相同内存"相关"并且预期共享相同的生命周期.
函数(new_int在您的情况下)可以通过两种方式分配内存:
参考(&)是指向内存区域的指针.它可以指向本地堆栈,也可以指向"堆".由于动态分配在性能方面比在堆栈上写入要昂贵得多,因此Rust默认使用堆栈(您必须使用Box来执行动态分配).
因此,简而言之,这就是您的代码非法的原因:
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
Run Code Online (Sandbox Code Playgroud)
您可以返回值
fn new_int() -> isize {
5
}
fn main() {
let a = new_int(); // the value 5 (not a pointer) is copied into a
}
Run Code Online (Sandbox Code Playgroud)
或执行动态分配(在isize的情况下是矫枉过正的,但如果您实际使用的是大型结构则可能有意义)
fn new_int() -> Box<isize> {
Box::new(5)
}
fn main() {
let a = *new_int();
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以在函数外部分配内存并在函数中对其进行变更.您通常不会为原始类型执行此操作,但在某些情况下(例如,数据流)有意义:
// 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
}
Run Code Online (Sandbox Code Playgroud)
正如@dk在下面的注释中提到的那样,在这种特定情况下(即你的函数总是返回5或其他一些静态已知值,而不是函数动态计算的东西),你也可以返回一个带有'static生命周期的引用:
fn new_int<'a>() -> &'a isize {
static FIVE: isize = 5;
&FIVE
}
Run Code Online (Sandbox Code Playgroud)
您可以static 在Rust Reference中阅读更多有关' 的信息.
从Rust 1.21开始,这个"静态促销"现在会自动为您执行并且您的原始代码会编译.它创造了相当于static FIVE.
理解原因的另一种方法
fn new_int<'a>() -> &'a isize {
&5
}
Run Code Online (Sandbox Code Playgroud)
不能正常工作如下.'a是函数的生命周期参数 ; 也就是说,调用者选择此参数的实际值,而不是函数本身.例如,调用者可以选择'static生命周期:
let i: &'static isize = new_int();
Run Code Online (Sandbox Code Playgroud)
但是,&5不能有'static生命,所以功能被拒绝.
换句话说,这种声明基本上是说"我可以给你一个你想要的任何生命的参考".当然,这仅在从函数返回的引用具有'static生命周期时才有效,这是可能的最大生命周期.这就是DK.顺便说一下.
生命周期仅描述代码已经在做什么。它们不会以任何方式影响代码的行为。
它们并不是让某些东西按照需要的时间运行的指令,而是一种一致性检查,以确保代码确实按照其规定执行。
事实上,Rust 在检查后从代码中剥离所有生命周期,然后在不了解生命周期的情况下编译代码。
变量在其作用域结束时被销毁,这就是它们的生命周期。你不能说声明他们没有这样做。