为scala不可变列表定义的`++ =`运算符在哪里?

时间:2016-05-16 21:55:55

标签: scala

如何在下面的代码中评估++=++=运算符应用于显式定义为不可变列表的类,该列没有++=运算符。 x ++= y似乎与x = x ++ y具有相同的行为,但我无法找到此行为的来源。这里发生了什么? (以及它在哪里记录?)

object ListConcatenation extends App {
  var list = scala.collection.immutable.List[Int](1)
  println(list)

  list = list ++ scala.collection.immutable.List[Int](2)
  println(list)

  // This operator does not exist on the List class, but has the same behavior as the operation above.
  list ++= scala.collection.immutable.List[Int](3)
  println(list)
}

输出

List(1)
List(1, 2)
List(1, 2, 3)

1 个答案:

答案 0 :(得分:7)

  

x ++ = y似乎与x = x ++ y

具有相同的行为

确实如此。

  

但我找不到这种行为的形式。

它内置于语言中。当x op= y无法解释为调用方法op=时(因为x的类或任何可以隐式转换为的类都不存在这样的方法),而是解释为调用方法op和赋值。

  

(它在哪里记录?)

在Scala的语言规范中,section 6.12.4

  

分配运营商

     

赋值运算符是一个运算符符号(标识符中的语法类别op),以等号“=”结尾,但运算符除外,其中包含以下条件之一:

     
      
  1. 运算符也以等号开头,或
  2.   
  3. 运算符是(<=),(>=),(!=)之一。
  4.         

    如果没有其他解释有效,则可以特别处理赋值运算符,因为它们可以扩展为赋值。

         

    让我们在中缀操作+=中考虑一个赋值运算符,例如l += r,其中lr是表达式。该操作可以被重新解释为对应于赋值的操作

    l = l + r
    
         

    除了操作的左侧l仅评估一次。

         

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

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