问题 什么时候+ = b变成了Scala中的a = a + b?


仅Scala 有时 desugars

a += b

a = a + b

但不总是。例如,一些可变集合定义了一个 += 相反,它变成了

a.+=(b)

这是行为吗?

  1. 完全取决于是否有合适的 += 方法 a? (包括有这种行为的其他例子吗?)
  2. 独立于对象是val还是var?

相关的例子

改编自 在Scala中编程,在

var s = Set("a", "b")
s += "c"

在这种情况下,第二行代码 s += "c" 基本上是简写:

s = s + "c"

5822
2017-08-21 15:28


起源

我之前做了一个仓促的回答,但我删除了它,因为它有很多概念上的错误,我做了一个新的,我希望它有所帮助。 - Damian Lattenero
注意:Scala语言规范中定义了“Scala”是什么意思。像你这样的问题的答案总是可以在那里找到,而且它们是 根据定义 正确答案。 - Jörg W Mittag


答案:


什么时候+ = b变成了Scala中的a = a + b?

什么时候没有适用 += 方法,那里  适用的 + 方法和 a 是可分配的(也就是说,它是一个 var 或者有一个 a_= 方法)。

或者作为 规范 把它:

如果满足以下两个条件,则重新解释。

  1. 左手边 l 没有名为的成员 +=,也无法通过隐式转换转换为具有名为的成员的值 +=
  2. 分配 l = l + r 是类型正确的。特别是这意味着 l 是指可以分配给的变量或对象,并且可以转换为具有名为的成员的值 +

这是行为吗?

  1. 完全取决于是否有合适的+ =方法?
  2. 独立于对象是val还是var?

不完全的。如果有合适的话 += 无论其他因素如何,都会调用它 a 可转让)。但是当没有时,其他因素决定它是否被消除或者你得到错误信息。

请注意,您获得的错误消息与您从desugared版本获得的错误消息不同:当desugaring的标准不适用时,您会收到一条错误消息,告诉您“+ =不是...的成员。“,加上解释为什么不能应用desugaring(例如”接收器不可分配“或你从中得到的类型错误 a + b 如果 a + b 会产生类型错误)。


9
2017-08-21 15:37



这个答案是完全正确的,但我可能会建议将其链接起来 相关的SLS 以供参考。 - Silvio Mayolo
@SilvioMayolo谢谢,我添加了一个链接和摘录。 - sepp2k
非常感谢你的评论,我犯了一个很大的错误,我做了一个仓促的回答,有很多概念上的错误。再次感谢,我现在纠正了 - Damian Lattenero


在我的第一个回答中,我有点仓促,道歉。经过一段时间的研究和更好的阅读@ sepp2k的回答和评论后,我得出结论,Scala中的一些类实现了 += 方法,和其他只是 + 方法,我用一些Scala代码玩了一下,例如:

  //Set, Int, Double, String implements the "+" method,
  //and then "+=" is syntactic sugar of a = a + b 
  var set = Set("a", "b")
  set += "c"

  var num = 3
  num += 2

  var str = "43"
  str += 5

  var l = List()
  l += "someString"

  // As you mention, MutableList implements "+=" method, and when you do
  // mutL += 4, is the same as call the method mutL.+=
  var mutL = new mutable.MutableList[Int]
  mutL += 4

0
2017-08-21 17:39