去掉$冒号$冒号令牌

时间:2018-01-05 23:44:53

标签: scala

当用作表达式时,当用作模式时,h::t被置于两个不同的东西中。这完全有意义,因为它在表达式中使用时,我们希望将::方法应用于t参数h,即t.$colon$colon(h);而当它在匹配的情况下使用时,我们希望将其识别为$colon$colon(h,t),即案例类模式。

在一种闲散的好奇心中,我想知道导致这两种不同解释的背景是什么。在表达式的情况下,我理解::是一种右关联方法,但在其他情况下它如何从h::t转到$colon$colon(h,t)

编辑:添加源代码以说明两种不同的上下文:

  def decode(xs: List[Int]): Unit =
    xs match {
      case Nil =>
      case h :: t => println(h::t); decode(t)
    }

1 个答案:

答案 0 :(得分:0)

正如jwvh指出的那样,你的问题不明确,并允许各种解释。无论如何,我会尝试回答一些更明显的问题:

:: vs $colon$colon

与许多传统语言不同,Scala允许定义自定义运算符,包括几乎所有符号,例如“:”。另一方面,Scala被编译到一些其他目标平台(例如JVM),这些平台不允许在方法名称中使用这些符号。为了解决这个问题,典型的解决方案是让编译器自动将“禁止”符号转换为一些罕见但有效的序列。 $colon只是:的序列。因此::转换为$colon$colon

中缀符号

友好的自定义运算符的另一个重点是允许infix notation,它也适用于只有一个参数而不仅仅是运算符的任何方法。例如,您也可以编写list map func,将其翻译为list.map(func)

模式匹配

模式匹配的Scala设计是明确可扩展的。这意味着您可以编写一个代码,使模式匹配适用于您的自定义类。您需要编写的代码是extractor object with unapply (or unapplySeq) method(有关不太重要的示例,请参阅this guide)。此外,对于case class,编译器会自动生成适当的unapply。如果您查看代码,可能会发现scala.collection.immutable.::实际上是case class