【问题标题】:Why is the ++: operator in the Scala language so strange?为什么 Scala 语言中的 ++: 运算符如此奇怪?
【发布时间】:2019-04-19 07:36:12
【问题描述】:

我使用++:操作符获取两个集合的集合,但是我使用这两种方法得到的结果不一致:

scala> var r = Array(1, 2)
r: Array[Int] = Array(1, 2)
scala> r ++:= Array(3)
scala> r
res28: Array[Int] = Array(3, 1, 2)

scala> Array(1, 2) ++: Array(3)
res29: Array[Int] = Array(1, 2, 3)

为什么++:++:= 运算符给出不同的结果? ++ 运算符不会出现这种差异。

我使用的 Scala 版本是 2.11.8。

【问题讨论】:

  • ++:++:= 的另一个有趣的效果是它从右侧获取结果集合的类型(如果它们不是这里的数组,stackoverflow.com/a/24338494/14955) --- 在++:= 存在的情况下对“右手”的一些定义。

标签: arrays scala collections assignment-operator


【解决方案1】:

因为它以冒号结尾,所以++: 是右结合的。这意味着Array(1, 2) ++: Array(3) 等价于Array(3).++:(Array(1, 2))++: 可以认为是“将左侧数组的元素添加到右侧数组”。

因为它是右结合的,所以 r ++:= Array(3) 脱糖到 r = Array(3) ++: r。当您认为++: 的目的是前置时,这是有道理的。这种脱糖对于任何以冒号结尾的运算符都是正确的。

如果要追加,可以使用++(和++=)。

【讨论】:

  • @Thilo +:::::: 浮现在脑海中。同样,它是以冒号结尾的任何内容。
  • @Thilo:Scala 中没有“运算符”这样的东西。任何方法都可以在没有句点的情况下调用:a foo(bar, baz),当您只传递一个参数时,可以省略括号,如下所示:a foo bar。而已。这只是一个普通的方法调用,而++ 只是一个普通的方法名称,如foo。不过,有两个例外,这意味着 Scala 实际上确实 有“半算子”。 1) 优先级由方法名的第一个字符决定。 2) 以: 结尾的方法在使用运算符语法调用时是右关联的。
  • 注意:这也适用于类型构造函数。所以,如果你有class Foo[A, B] {},那么你当然可以说def foo: Foo[Int, String],但你也可以说def foo: Int Foo String,如果你有class Foo_:[A, B],那么Foo_:[Int, String]String Foo_: Int是一样的。跨度>
  • 啊,对不起。我的错。 :: 是一元的,而不是二元的。但可能有人正在这样做。
  • @JörgWMittag 类型构造函数可以是右关联的(shapeless.:: 就是一个例子),但在这种情况下它们不会交换参数的顺序(谢天谢地)。
【解决方案2】:

这里的冒号(:)表示函数具有右结合性

所以,例如coll1 ++: coll2 类似于(coll2).++:(coll1)

这通常意味着左集合的元素被添加到右集合

案例一:

Array(1,2) ++: Array(3)
Array(3).++:Array(1,2) 
Elements of the left array is prepended to the right array 
so the result would be Array(3,1,2)

案例 2:

 r = Array(1,2)
 r ++:= Array(3) //This could also be written as the line of code below
 r = Array(3) ++: r
   = r. ++: Array(3)
   = Array(1,2). ++: Array(3) //Elements of the left array is prepended to the right array 
 so their result would be Array(1,2,3)

希望这能解决问题 谢谢:)

【讨论】:

  • ++: 是一个方法,而不是一个函数。
猜你喜欢
  • 2013-05-13
  • 2018-10-30
  • 2012-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多