【问题标题】:Why isn't this rvalue promoted to an lvalue as specified in the reference?为什么不将此右值提升为参考中指定的左值?
【发布时间】:2017-05-22 02:21:22
【问题描述】:

Rust Reference 说:

赋值或复合赋值表达式的左操作数是左值上下文,一元借位的单个操作数也是如此。

[...]

当在左值上下文中使用右值时,会创建并使用一个临时的未命名左值。

这种右值提升显然适用于借用:

let ref_to_i32 = &27;  // a temporary i32 variable with value 27 is created

但它似乎在赋值中不起作用(尽管参考文献谈到了所有左值上下文,而不仅仅是借用):

27 = 28;   // error[E0070]: invalid left-hand side expression

error description of E0070 没有提到这个右值促销。这是引用中的错误,还是确实有某种方法可以通过赋值或复合赋值表达式触发右值提升?

还有第三种左值上下文,参考资料也描述不正确。只要有一个带有ref 的模式,绑定到该模式的左值就是一个左值上下文。事实证明,促销在​​这种情况下有效:

let ref x = 3;  // works

显然,促销只对(复合)作业不起作用?

【问题讨论】:

  • 有趣的是,*&mut 27 = 28; 确实可以编译。
  • @mcarton 在您的示例中,促销是由于借用运算符而不是赋值运算符而发生的。但确实很有趣^_^
  • 相关:文档似乎还说let mut a = 1; *&mut (a) = 2; assert_eq!(a, 1); 应该通过:(a) 中的a 不是&mut 的操作数,因此应该转换为右值。 (a) 然后是一个右值,它是&mut 的操作数,所以应该从它创建一个临时的,并且应该分配这个临时的2。而是将a 分配给2。 (更简单的说法是 (a) = 2; 应该被拒绝,但我认为无论以哪种方式编译但在运行时具有不同行为的代码更有趣。)不过,对于您和我的代码而言,编译器行为是有意义的。

标签: rust language-lawyer rvalue lvalue


【解决方案1】:

The reference 自发布此问题以来已更新。现在它说在赋值期间不会发生从右值到左值的提升,所以这显然是旧参考中的一个错误。

Borrow operators:

如果 & 或 &mut 运算符应用于右值,则会创建一个临时值

这可能也适用于ref 绑定,尽管我没有看到明确提及。

Assignment:

左侧操作数必须是左值:使用右值会导致编译器错误,而不是将其提升为临时值。

【讨论】:

  • let ref _ = rvaluelet _ = &rvalue 不是一回事吗?我相信它也适用于 ref 绑定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-06
  • 1970-01-01
相关资源
最近更新 更多