这是我的代码:
fn main() {
fn fizz_buzz<'a>(i: i32) -> &'a str {
if i % 15 == 0 {
"FizzBuzz"
} else if i % 5 == 0 {
"Buzz"
} else if i % 3 == 0 {
"Fizz"
} else {
&i.to_string()
}
}
for i in 1..101 {
println!("{}" , fizz_buzz(i));
}
}
编译器给我这个错误:
error[E0515]: cannot return reference to temporary value
--> src/main.rs:11:9
|
11 | &i.to_string()
| ^-------------
| ||
| |temporary value created here
| returns a reference to data owned by the current function
For more information about this error, try `rustc --explain E0515`.
error: could not compile `playground` due to previous error
我试过一辈子一成不变。
2条答案
按热度按时间wfsdck301#
你的函数将正确给予一个对字符串“FizzBuzz”、“Buzz”和“Fizz”的引用(它们的生存期是静态的,因为它们是在中编译的),但是
&i.to_string()
没有相同的属性,让我们详细看看生存期:当
fizz_buzz
被调用时,i
被复制(因为i32实现了Copy特性)并被赋予它,但是在else代码块中,我们做了以下操作:1.创建新拥有的
String
1.返回对该
String
的引用然而,
String
的生命周期只有fizz_buzz函数调用的时间!因为我们需要在该作用域之外使用它的引用,Rust调用了foul。有几种方法可以使这种类型安全。你可以返回拥有的值而不是引用:
尽管这最终会在堆上创建许多相同的对象(例如,考虑一下有多少个“Fizz“)
我更喜欢的另一个选项是让fizz_buzz返回一个Option〈&str〉,并让调用作用域处理fizz_buzz返回None的情况。
正如@RobinZigmond在评论中指出的,您还可以返回一个枚举并为它实现Display。
nxagd54h2#
你试图返回一个只存在于堆栈帧中的值的引用,这个堆栈帧在你退出函数时会消失。
关键的一点是,
String
是一个存在于 heap 上的字符串,而不是存在于 stack 上的字符串,创建动态字符串的唯一方法(例如,将i32强制转换为字符串时所做的)是将其放在堆栈上,因此,必须更改方法签名。(不过,我更喜欢亚当·斯密的回答!它清楚地表明了鲁斯特的生命周期概念是如何影响这一点的。)