Rust中的左值上下文到底是什么?

Rom*_*man 1 type-inference rust

根据文档,我们有左值和右值上下文。我如何知道表达式是否在左值上下文中?它是否仅由赋值中的表达式确定?

更具体地讲,我需要了解何时DerefMut用于取消引用以及何时用于反引用Deref?与Index和相同IndexMut

Luk*_*odt 5

您在这里问两个不同的问题。

更具体地说,我需要了解,什么时候DerefMut用于取消引用,什么时候Deref代替?与Index和相同IndexMut

这仅取决于结果值是否可更改地使用。使用属于这些特征([]*)的运算符的表达式始终是左值表达式


现在,您的问题更加复杂:

我如何知道表达式是否在左值上下文中?它是否仅由赋值中的表达式确定?

表达类别

回顾一下:什么是右值/左值表达式

  • 一个右值表达式表示一个值
  • 一个左值表达式代表在存储器位置的值(或者在不同的词:表示住某处的值/具有归属)

哪些表达式是左值表达式,哪些是右值表达式?只有几个l值表达式:

  • 引用变量(本地,函数参数或静态变量)的“名称”(或更确切地说:路径)
  • 索引表达式(例如foo[3]
  • 反引用表达式(例如 *foo
  • 字段访问表达式(例如foo.bar

上下文类别

右值/左值上下文呢?这些上下文是表达式内的“槽”。例如,表达式“ modulo”(%)具有其中两个插槽,第一个和第二个操作数:?first? % ?second?。现在,这些上下文也具有两种不同的风格:

  • 一个右值上下文是一个“槽”,其中期望值
  • 左值上下文是其中“时隙” 的存储器位置,预计

那么哪些插槽是右值,哪些插槽是左值上下文?幸运的是,l值上下文的数量非常有限,因此下面是完整列表:

  • (复合)赋值(例如?lvalue context? = ...;?lvalue context? += ...;)的左侧
  • 一元借位(&?lvalue context?&mut ?lvalue context?)的操作数
  • 每当将某事物绑定到其中ref出现a的模式时(例如let ref x = &?lvalue context?;

在上下文Y中使用表达式X

让我们看看我们可以在哪种上下文中使用哪些表达式

  • [在R R] - [R值的表达ř值上下文:没有问题,表达被用作值(例如,文字3上的分配的右手侧)
  • [L在L] 值表达值上下文:没有问题,表达被用作存储位置(在赋值的左手侧例如变量名)
  • [L中R] 值表达ř值上下文:因为上下文需要的值,并且所述表达表示“在存储器位置的值”,我们可以只使用表达式的值。因此:一切都很好(例如,赋值右侧的变量名称)。因此我们可以看到:左值表达式右值表达式更有价值。
  • [L中的R]l值上下文中的r值表达式:这是有问题的地方。上下文需要一个内存地址,但是表达式仅表示一个值。有时,Rust会进行“升值促销”以使这种情况发生。这意味着Rust将自动将表达式的值放入新的内存位置(一个临时变量),并在上下文中使用该位置。例如,由于所说的晋升而工作。此促销当前不适用于分配,这似乎是文档或编译器中的错误&mut 3