当用作表达式时,当用作模式时,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)
}
答案 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
。