You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

变量重新赋值引发Rust生命周期问题求解

Rust生命周期困惑:临时值赋值的差异解析

问题背景

我在完成rustlings练习时遇到了生命周期相关的困惑,将代码简化为核心部分如下:

可正常编译的代码

fn string_uppercase(mut data: &String) {
    let newdata: &String = &data.to_uppercase();
}

无法编译的代码

fn string_uppercase(mut data: &String) {
    data = &data.to_uppercase();
}

报错信息

error[E0716]: temporary value dropped while borrowed
  --> exercises/06_move_semantics/move_semantics6.rs:25:13
   |
24 | fn string_uppercase(mut data: &String) {
   |                               - let's call the lifetime of this reference `'1`
25 |     data = &data.to_uppercase();
   |     --------^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
   |     |       |
   |     |       creates a temporary value which is freed while still in use
   |     assignment requires that borrow lasts for `'1`

error: aborting due to 1 previous error; 1 warning emitted

我已经理解两点:

  • data.to_uppercase()会创建一个新的String
  • 该值是表达式生成的临时值,未存入变量会被销毁

但疑惑的是:将临时值存入newdata和存入原变量data的区别是什么?两者都是试图保存临时值避免其被销毁,为何一个可行一个报错?

核心原因:生命周期约束的差异

这两种写法的本质区别在于变量的生命周期要求不同:

  1. 存入newdata的情况
    newdata是函数内新声明的变量,它的生命周期只需要覆盖自身的作用域(从声明到函数结束)。Rust有一个临时值延长规则:当临时值的引用被绑定到一个新的局部变量时,临时值的生命周期会被延长到和这个变量一致。所以data.to_uppercase()生成的临时String会一直存活到函数结束,newdata的引用自然有效,不会报错。

  2. 存入原变量data的情况
    原变量data的类型是&String,它的生命周期被函数签名约束为'1——也就是和函数传入的引用生命周期一致。当你把&data.to_uppercase()赋值给data时,Rust要求这个新引用的生命周期必须等于'1,但临时值的生命周期只能到当前语句结束(即使没有绑定到新变量),远短于'1。临时值销毁后,data就会变成一个悬垂引用,这违反了Rust的内存安全规则,所以编译器直接报错。

简单说:新变量newdata没有被强制要求必须持有某个长生命周期的引用,而原变量data的生命周期是被函数签名固定死的,临时值撑不到那么久。

内容的提问来源于stack exchange,提问作者Nicola Pedretti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 01:51:23