【问题标题】:++: does not appear to be right associative?++:似乎不是右联想?
【发布时间】:2019-07-31 16:25:34
【问题描述】:

我正在尝试学习 scala。我正在查看有关队列的文档 (https://www.scala-lang.org/api/current/scala/collection/immutable/Queue.html)。

据我了解,以冒号结尾的方法是右结合的。但是,对我来说,++: 似乎并没有这样做:

import scala.collection.immutable.Queue
val q0 = Queue(0)
val q1 = Queue(1)
q0 ++ q1 // yields Queue(0,1) as I expected
q0 ++: q1 // yields Queue(0,1) as well;  I expected Queue(1,0)

文档和实验似乎都表明 ++: 不是正确关联的。 ++ 和 ++ 的文档:说左后跟右,这就是上面发生的事情,我只是不明白为什么。显然,我缺少一些东西。有人可以帮我澄清一下吗?

【问题讨论】:

  • 为什么你会期待不同的结果?该方法的文档清楚地表明它给出了与++: 相同的结果。我懒得去查了,但我假设它只是简单地实现为def ++:(other) = other ++ this

标签: scala syntactic-sugar associativity


【解决方案1】:

一个非常简单的实验:

case class A(s: String) { def ++:(a: A) = A(s"(${a.s} + ${s})") }
A("x") ++: A("y") ++: A("z")

给予:

A((x + (y + z)))

所以它是x + (y + z) 而不是(x + y) + z。因此,正如宣传的那样,++: 是右关联的。

请注意,它是 ${a.s} + ${s} 而不是 ${s} + ${a.s}。在Queue 的情况下,它可能是类似的,类似于:

def ++:(left: Queue[A]): Queue[A] = left ++ this

因此,当您编写 q0 ++: q1 时,元素的顺序会显示为“应有的样子”,它会脱糖成 q1.++:(q0),然后扩展成 q0 ++ q1

【讨论】:

  • 谢谢。最后一句话为我澄清了这一点。我发现它...有趣的是它与 q1 开始是右关联的,但是当您用点符号重写它时,它会与 q0 右关联。由于 ++ 和 ++: 似乎给出了相同的结果,那么您什么时候使用一个与另一个?
  • @WilliamAllcock 对于++++:code 似乎几乎相同,只是thisthat 的角色互换了。因此,差异似乎纯粹是表面上的。当你想强调右边的队列是“大而稳定”的东西,而左边的队列是一些“小增量”时,也许你可能想使用++:。老实说,我不记得我曾经用过++: 做任何事情。
  • 非常混乱。 2.13 文档说++concat 的别名,++:prependedAll 的别名。快速检查表明预先准备是昂贵的。并不是说concatappendedAll 的别名。检查解析的快速方法是 REPL 中的q0 ++: q1 //print<TAB>
  • @AndreyTyukin 我在上面给出的代码链接的 cmets 中发现了这一点: * 它与 ++ 的不同之处在于右操作数决定了结果集合的类型,而不是左操作数。 * 助记符:COLon 在新的 COLlection 类型的一侧。
  • @WilliamAllcock Wellyeah... 那么,归根结底,它告诉我们什么? “方法返回值的类型由方法的返回类型决定”?真的......很难与那个争论。助记符似乎很奇怪。看起来像是方法的作者想出的东西,然后十分钟后忘记了。
猜你喜欢
  • 2017-12-31
  • 1970-01-01
  • 2019-03-09
  • 2020-06-25
  • 1970-01-01
  • 2013-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多