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

关于Rust可变引用作用域规则与代码编译结果不符的疑问

Rust可变引用规则的疑问:为何这段代码能编译通过?

问题背景

我正在学习Rust中的引用,《Programming Rust》里提到:

只要存在值的共享引用,即使其所有者也无法修改该值;若存在值的可变引用,它拥有对该值的独占访问权,在可变引用失效前,所有者完全无法使用该值。

但我写的这段代码却能正常编译:

let mut a = vec![1, 2, 3];
let b = &mut a;
b.push(5);
a.push(4);

按照书中描述,可变引用b仍在作用域内时,a.push()应该编译失败,想纠正我的错误认知。


解答:Rust的非词法生命周期(NLL)

你之前的认知是基于词法作用域的旧规则,但Rust 1.31版本引入了非词法生命周期(Non-Lexical Lifetimes, NLL),编译器会智能分析引用的最后一次使用位置,而不是简单以代码块的作用域作为引用失效的边界。

在你的代码里,b的最后一次使用是b.push(5);这一行,执行完这行后,b就再也没有被用到了。编译器会判定b的生命周期在这里就结束了,所以之后对a的访问(a.push(4);)不会和b的可变引用产生冲突,因此可以正常编译。

如果调整代码顺序,让b的使用在a.push()之后:

let mut a = vec![1, 2, 3];
let b = &mut a;
a.push(4); // 这里会编译错误
b.push(5);

此时编译器就会报错,因为b的最后一次使用在a.push()之后,a的访问和b的独占可变引用产生了冲突,符合你最初理解的规则。

简单来说,NLL让编译器更精准地判断引用的有效范围,避免了很多不必要的编译错误,同时依然保证了Rust的内存安全。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 23:15:33