首页 > 解决方案 > 在 Rust 中可变地借用文字的语义是什么?

问题描述

我发现这可以编译:

let x = &mut 10;
*x = 20;

这非常令人困惑。可变借用文字的语义是什么?

我来自 C++,编译器绝对不允许我像这样引用右值:

int *x = &10;
int &y = 10;

标签: rustsemanticsliteralsborrowing

解决方案


与 C++ 一样,Rust 也有右值和左值的概念。该参考称它们为值表达式(右值)和位置表达式(左值)。此外,还有值上下文位置上下文(表达式/语句中的插槽,分别需要值表达式或位置表达式)。

当值表达式(如文字)用于位置上下文(如借用运算符&时,Rust 有特殊规则。从参考

在大多数位置表达式上下文中使用值表达式时,会创建一个临时未命名的内存位置,并初始化为该值,并且表达式会计算为该位置而不是 [...]。

所以 Rust 会自动将你的值存储10在内存位置。内存位置的生命周期取决于值表达式的使用方式,但在您的情况下,未命名的内存位置与封闭块具有相同的生命周期。因此它等价于隐藏let绑定:

let _compiler_generated = 10;
let x = &mut _compiler_generated;
*x = 20;

这不仅适用于文字:

fn get_u32() -> u32 { 3 }

let x = &mut get_u32();
*x = 20;

虽然对那些熟悉对象生命周期如何在 C++ 等语言中工作的人感到困惑,但在某些情况下,这是一个相当有用的特性。


相关:如果您对文字使用im可变引用,则该值不仅会写入堆栈槽,还会写入静态内存。意思let _: &'static u32 = &10是有效的!这已在RC 1414中指定。


推荐阅读