Rust 中的左值上下文到底是什么? [英] What is exactly lvalue context in Rust?

查看:34
本文介绍了Rust 中的左值上下文到底是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

According to the documentation, we have lvalue and rvalue contexts. How do I know if an expression is in an lvalue context? Is it determined just by the side of the expression in an assignment?

更具体地说,我需要了解何时使用 DerefMut 进行解引用,何时使用 Deref 代替?与 IndexIndexMut 相同.

To be more concrete, I need to understand when DerefMut is used for dereferencing and when Deref is used instead? Same with Index and IndexMut.

推荐答案

您在这里问了两个不同的问题.

You are asking two different questions here.

更具体地说,我需要了解,何时使用 DerefMut 进行解引用,何时使用 Deref 代替?与 IndexIndexMut 相同.

To be more concrete, I need to understand, when DerefMut is used for dereferencing and when Deref is used instead? Same with Index and IndexMut.

这仅取决于结果值是否可变使用.使用属于这些特征([]*)的运算符的表达式总是左值表达式.

This only depends on whether or not the resulting value is used mutably or not. The expressions using the operators belonging to those traits ([] and *) are always lvalue expressions.

现在你的问题更复杂:

我怎么知道表达式是否在左值上下文中?是否仅由赋值中的表达式一侧决定?

How do I know, if an expression is in an lvalue context? Is it determined just by the side of the expression in an assignment?

表达类别

总结:什么是右值/左值表达式?

  • 一个右值表达式代表一个值
  • 一个左值表达式表示内存位置中的一个值(或者换一种说法:表示一个住在某处/有一个家的值)
  • an rvalue expression represents a value
  • an lvalue expression represents a value in a memory location (or in different words: represents a value which lives somewhere/has a home)

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

Which expressions are lvalue and which are rvalue expressions? There are only a few lvalue expressions:

  • 名称"(或者更确切地说:路径)引用变量(局部、函数参数或静态)
  • 索引表达式(例如 foo[3])
  • deref 表达式(例如 *foo)
  • 字段访问表达式(例如 foo.bar)

右值/左值上下文怎么样?这些上下文是表达式中的槽".例如,表达式模"(%)有两个这样的槽,第一个和第二个操作数:⟨first⟩ % ⟨second⟩.现在这些上下文也有两种不同的风格:

What about rvalue/lvalue contexts? These contexts are "slots" inside of expressions. For example, the expression "modulo" (%) has two of those slots, the first and the second operand: ⟨first⟩ % ⟨second⟩. Now these contexts come in two different flavours as well:

  • 右值上下文是一个槽",其中期望值
  • 左值上下文是一个槽",其中需要一个内存位置
  • an rvalue context is a "slot" where a value is expected
  • an lvalue context is a "slot" where a memory location is expected

那么哪些插槽是右值,哪些是左值上下文?幸运的是,l值上下文的数量非常有限,所以这里是一个完整的列表:

So which slots are rvalue and which are lvalue contexts? Luckily, the number lvalue contexts is very limited, so here is a full list:

  • (复合)赋值的左侧(例如 ⟨lvalue context⟩ = ...;⟨lvalue context⟩ += ...;)
  • 一元借用的操作数(&⟨lvalue context⟩ and &mut ⟨lvalue context⟩)
  • 每当某些东西被绑定到一个出现 ref 的模式时(例如 let ref x = &⟨lvalue context⟩;)
  • the left hand side of a (compound-)assignment (e.g. ⟨lvalue context⟩ = ...; or ⟨lvalue context⟩ += ...;)
  • the operand of an unary borrow (&⟨lvalue context⟩ and &mut ⟨lvalue context⟩)
  • whenever something is bound to a pattern in which a ref appears (e.g. let ref x = &⟨lvalue context⟩;)

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

Let's see which expressions we can use in which context:

  • [R in R] r值表达r值上下文:没问题,表达式用作值(例如赋值右侧的文字 3)
  • [L in L] l价值表达l价值上下文: 没问题,表达式用作内存位置(例如赋值左侧的变量名)
  • [L in R] l值表达r值上下文:由于上下文需要一个值,并且表达式表示内存位置中的值",我们可以只使用表达式的值.所以:一切都很好(例如,赋值右侧的变量名).所以我们可以看到:左值表达式右值表达式更有价值.
  • [R in L] r值表达l值上下文: 这就是问题所在.上下文需要一个内存地址,但表达式只代表一个值.有时,Rust 会做一个右值提升"来使这样的情况起作用.这意味着 Rust 会自动将表达式的值放入一个新的内存位置(一个临时变量)并在上下文中使用该位置.例如, &mut 3 由于上述促销而起作用.此促销目前不适用于 似乎是文档或编译器中的错误.
  • [R in R] rvalue expression in rvalue context: no problem, the expression is used as value (e.g. the literal 3 on the right hand side of an assignment)
  • [L in L] lvalue expression in lvalue context: no problem, the expression is used as memory location (e.g. a variable name on the left hand side of an assignment)
  • [L in R] lvalue expression in rvalue context: since the context requires a value and the expression represents a "value in a memory location" we can just use the value of the expression. So: it's all fine (e.g. a variable name on the right hand side of an assignment). So we can see: lvalue expressions are worth more than rvalue expressions.
  • [R in L] rvalue expression in lvalue context: here is where it becomes problematic. The context requires a memory address, but the expression only represents a value. Sometimes, Rust will do an "rvalue promotion" to make situations like this work. This means that Rust will automatically put the value of the expression into a new memory location (a temporary variable) and use that location in the context. For example, &mut 3 works because of said promotion. This promotion currently doesn't work for assignments, which seems to be a bug in either the documentation or the compiler.

这篇关于Rust 中的左值上下文到底是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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