在 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 contexts 和 place 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.
中指定
我发现这个是可以编译的:
let x = &mut 10;
*x = 20;
这很令人困惑。可变借用文字的语义是什么?
我来自 C++,编译器肯定不允许我这样引用右值:
int *x = &10;
int &y = 10;
和C++一样,Rust有右值和左值的概念。参考文献称它们为值表达式(右值)和放置表达式(左值)。此外,还有 value contexts 和 place 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.