我发现这可以编译:
let x = &mut 10;
*x = 20;
这非常令人困惑。可变借用文字的语义是什么?
我来自 C++,编译器绝对不允许我像这样引用右值:
int *x = &10;
int &y = 10;
与 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中指定。