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

时间:2018-07-15 03:23:16

标签: rust semantics literals borrowing

我发现它可以编译:

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

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

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

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

1 个答案:

答案 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中指定。