在Rust中可变地借用一个字面量的语义是什么?[duplicate]

xoefb8l8  于 2023-01-17  发布在  其他
关注(0)|答案(1)|浏览(116)
    • 此问题在此处已有答案**:

Why is it legal to borrow a temporary?(3个答案)
Why isn't this rvalue promoted to an lvalue as specified in the reference?(1个答案)
四年前关闭了。
我发现这是能够编译:

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

这是非常令人困惑的。什么是语义的可变借用一个字面值?
我来自C++,在那里编译器肯定不允许我引用这样的右值:

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

3ks5zfa01#

和C++一样,Rust也有右值和左值的概念。参考文献称它们为 value expressions(右值)和 place expressions(左值)。此外,还有 *value context * 和 *place context *(表达式/语句内部的插槽,分别需要值表达式或位置表达式)。

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是有效的!这已经在RFC 1414中被指定了。

相关问题