在Rust中可变地借用文字的语义是什么? [英] What are the semantics of mutably borrowing a literal in Rust?

查看:97
本文介绍了在Rust中可变地借用文字的语义是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现它可以编译:

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

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

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

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

解决方案

与C ++一样,Rust具有右值和左值的概念.该引用称它们为值表达式(rvalue)和位置表达式(lvalue).另外,还有 value上下文 place上下文(在表达式/语句内部的插槽,分别需要使用值表达式或位置表达式).

对于在场所上下文中使用值表达式(例如文字)(例如借位运算符&),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 中指定. /p>

I found that this is able to compile:

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

This is very confusing. What are the semantics of mutably borrowing an literal?

I come from C++, where the compiler will definitely not allow me to refer to a rvalue like this:

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

解决方案

Like C++, Rust has the concept of rvalues and lvalue. The reference calls them value expressions (rvalue) and place expressions (lvalue). Additionally, there are value contexts and place contexts (slots inside of expressions/statements where a value expression or place expression, respectively, is expected).

Rust has special rules for when a value expression (like a literal) is used in a place context (like the borrow operator &). From 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 [...].

So Rust automatically stores your value 10 in a memory location. The lifetime of the memory location varies depending on how the value expression is used, but in your case, the unnamed memory location has the same lifetime as the enclosing block. It thus is equivalent to a hidden let binding:

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

This doesn't just work with literals:

fn get_u32() -> u32 { 3 }

let x = &mut get_u32();
*x = 20;

While being confusing to those familiar with how lifetimes of objects work in languages like C++, this is a fairly useful feature in a few situations.


Related: if you use an immutable reference to a literal, the value is not just written to a stack slot, but into static memory. Meaning that let _: &'static u32 = &10 is valid! This has been specified in RC 1414.

这篇关于在Rust中可变地借用文字的语义是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆