我发现它可以编译:
let x = &mut 10;
*x = 20;
这非常令人困惑。可变借用文字的语义是什么?
我来自C ++,编译器绝对不允许我这样引用右值:
int *x = &10;
int &y = 10;
答案 0 :(得分:4)
像C ++一样,Rust具有右值和左值的概念。该引用称它们为值表达式(rvalue)和位置表达式(lvalue)。另外,还有 value上下文和 place上下文(在表达式/语句内部的插槽,分别需要使用值表达式或位置表达式)。
对于在场所上下文(例如借位运算符&
中)使用值表达式(如文字)的情况,Rust有特殊的规则。来自the reference:
在大多数位置表达式上下文中使用值表达式时,会创建一个临时的未命名存储位置,并初始化为该值,然后表达式求值到该位置。[...]
因此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中指定。