在 Rust 中可变借用文字的语义是什么?

What are the semantics of mutably borrowing a literal in Rust?

我发现这个是可以编译的:

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

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

我来自 C++,编译器肯定不允许我这样引用右值:

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

和C++一样,Rust有右值和左值的概念。参考文献称它们为值表达式(右值)和放置表达式(左值)。此外,还有 value contextsplace contexts(expressions/statements 内的插槽,其中分别需要值表达式或位置表达式).

Rust 对于在位置上下文中使用值表达式(如文字)(如借用运算符 & 有特殊规则。来自 the reference:

When using a value expression in most place expression contexts, a temporary unnamed memory location is created initialized to that value and the expression evaluates to that location instead [...].

因此 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.

中指定